Order Invoices API

The Order Invoices API is an order API that allows you to tell Google what the customer paid for and how much you should be paid in a much more detailed way than you can with just the orders.shiplineitem method. However, using this API requires changes in the life cycle of an order if you are currently integrated with the Orders API.

After using orderinvoices.createchargeinvoice to create an invoice for an order, if a customer requests a refund directly (not through Google) you must use orderinvoices.createrefundinvoice to process the refund. If a customer requests a refund through Google, we recommend using orderreturns.process (v2.1 only), which is simpler than orderinvoices.createchargeinvoice. You can also use orders.refunditem (v2.1 only) to generate refunds without marking items as returned. If you are using v2 of the API, you must use orderinvoices.createchargeinvoice instaed of orders.refund or orders.returnrefundlineitem, regardless of how the refund was requested.

v2 to v2.1 changes

The principal differences between the old workflow and the new workflow are:

  • The new system allows for more detail in the pricing including

    • Pre-tax price
    • Taxes
    • Fees
    • Other amounts
  • The new system is incompatible with the refund method.

  • For refund requests not initiated through Google, you must call orderinvoices.createrefundinvoice instead of orderreturns.process to process the return.

  • You must call orderinvoices.createchargeinvoice after orders.shiplineitems.

To use the Order Invoices API, you must call the orderinvoices.createchargeinvoice after orders.shiplineitems to identify the shipping groups and specify the pricing structure of the order.

This document goes into much more detail but briefly, if you have code that uses the old (v2) refund API you will need to do a few things to get it to use the new Order Invoices API. This list represents the minimum; there is more information in the rest of the document.

  • Add the shippingGroupId field to your orders.shiplineitems call.
  • Call orderinvoices.createchargeinvoice after the orders.shiplineitems call.
  • Call orderinvoices.createrefundinvoice instead of orders.refund or orders.returnrefundlineitem.

orders.shiplineitems

The Order Invoices API begins with the orders.shiplineitems call. The call is the same as before except for one addition: the shipmentGroupId which is a new required field. In general, we have the following two use cases:

Line items with same charges (most common)

If the line items do not have different charges (for example, the same product value, shipping charges, etc.) based on which shipment they are in, you should use the same shipmentGroupId for all the orders.shiplineitems calls.

Here's a sample call to orders.shiplineitems with one shipmentGroupId:

{
  "operationId": "ship1",
  "lineItems": [
    {
    "lineItemId": "YYFPTREDYNCZEYE",
      "quantity": 2
    },
    {
      "productId": "online:en:US:df4sg53ds9",
      "quantity": 1
    }
  ],
  "shipmentGroupId": "shipmentgroup1",
  "shipmentInfos": [
    {
      "shipmentId": "shipment1",
      "carrier": "UPS",
      "trackingId": "1234567890"
    }
  ]
}

Subsequent calls use the same shipmentGroupId.

Line items with different charges (less common)

If the line items have different shipping charges, for example, source warehouse, weight based rates, etc., you can differentiate charges using different shipmentGroupIds (a less common case). The only reason to have different shipmentGroupId values within the same order is if you want to create different invoices for those items. If you want to do that you need to call orders.shiplineitems once for each separate shipmentGroupId.

Here's a series of calls using unique shipmentGroupIds:

shipmentgroup1

{
  "operationId": "ship1",
  "lineItems": [
    {
    "productId": "online:en:US:d3k3245",
      "quantity": 2
    }
  ],
  "shipmentGroupId": "shipmentgroup1",
  "shipmentInfos": [
    {
      "shipmentId": "shipment1",
      "carrier": "UPS",
      "trackingId": "1234567890"
    }
  ]
}

shipmentgroup2

{
  "operationId": "ship2",
  "lineItems": [
      {
      "productId": "online:en:US:df4sg53ds9",
      "quantity": 1
    }
  ],
  "shipmentGroupId": "shipmentgroup2",
  "shipmentInfos": [
    {
      "shipmentId": "shipment2",
      "carrier": "UPS",
      "trackingId": "1234567891"
    }
  ]
}

orderinvoices.createchargeinvoice

Once you have called orders.shiplineitems for a set of items, you need to create an invoice. You do that by calling the orderinvoices.createchargeinvoice method.

POST https://shoppingcontent.googleapis.com/content/v2.1/merchantId/orderinvoices/orderId/createChargeInvoice
POST https://shoppingcontent.googleapis.com/content/v2.1sandbox/merchantId/orderinvoices/orderId/createChargeInvoice

You need to call orderinvoices.createchargeinvoice at least once for each shipmentGroupId that you set in orders.shiplineitems.

Here's a sample orderinvoices.createchargeinvoice call with two line items, one of which has two units:

{
  "invoiceId": "invoice1",  // Defined by merchant
  "operationId": "charge1",
  "shipmentGroupId": "shipmentgroup1",
  "lineItemInvoices": [
    {
      "productId": "online:en:US:d3k3245",
      "shipmentUnitIds": [// Quantity of 2
        "unit1",
        "unit2"
      ],
      "unitInvoice": {
        "unitPricePretax": {
          "value": "70",
          "currency": "USD"
        },
        "unitPriceTaxes": [
          {
            "taxType": "sales",
            "taxAmount": {
              "value": "7",
              "currency": "USD"
            }
          }
        ]
      }
    },
    {
      "productId": "online:en:US:df4sg53ds9",
      "shipmentUnitIds": [// Quantity of 1
        "unit1"
      ],
      "unitInvoice": {
        "unitPricePretax": {
          "value": "399.85",
          "currency": "USD"
        },
        "unitPriceTaxes": [
          {
            "taxType": "sales",
            "taxAmount": {
              "value": "39.85",
              "currency": "USD"
            }
          }
        ],
        "additionalCharges": [
          {
            "type": "shipping",
            "additionalChargeAmount": {
              "pretax": {
                "value": "21.35",
                "currency": "USD"
              },
              "tax": {
                "value": "2.13",
                "currency": "USD"
              }
            }
          }
        ]
      }
    }
  ],
  "invoiceSummary": {
    "productTotal": {
      "pretax": {
        "value": "679.85",
        "currency": "USD"
      },
      "tax": {
        "value": "67.85",
        "currency": "USD"
      }
    },
    "additionalChargeSummaries": [
      {
        "totalAmount": {
          "pretax": {
            "value": "21.35",
            "currency": "USD"
          },
          "tax": {
            "value": "2.13",
            "currency": "USD"
          }
        },
        "type": "shipping"
      }
    ]
  }
}

Line items

For each line item, you need to specify either the lineItemId or the productId.

lineItemId from orders.list

...
 "lineItemInvoices": [
    {
      "lineItemId": "5VYPTREPXNCZEYE",
...

productId

...
"lineItemInvoices": [
    {
      "productId": "online:en:US:df4sg53ds9",
...

Each line item invoice consists of a pretax price (a value and a currency) which is required and zero or more "taxes" (sales tax).

There is also a section called shipmentUnitIds, but let's ignore that for now; we'll get back to it in a bit.

Sample line item invoice

...
 "lineItemInvoices": [
    {
      "productId": "online:en:US:d3k3245",
      "shipmentUnitIds": [
        "unit1",
        "unit2"
      ],
      "unitInvoice": {
        "unitPricePretax": {
          "value": "70",
          "currency": "USD"
        },
        "unitPriceTaxes": [
          {
            "taxType": "sales",
            "taxAmount": {
              "value": "7",
              "currency": "USD"
            }
          }
        ]
      }
    },
...

You can also specify additional charge amounts. Currently, the only allowed "additional charge amounts" are shipping charges. The shipping charges can be associated with any of the line items.

Sample line item invoice with additional charges

...
  "lineItemInvoices": [
    {
      "productId": "online:en:US:d3k3245",
      "shipmentUnitIds": [
        "unit1",
        "unit2"
      ],
      "unitInvoice": {
        "unitPricePretax": {
          "value": "70",
          "currency": "USD"
        },
        "unitPriceTaxes": [
          {
            "taxType": "sales",
            "taxAmount": {
              "value": "7",
              "currency": "USD"
            }
          }
        ],
        "additionalCharges": [
          {
            "type": "shipping",
            "additionalChargeAmount": {
              "pretax": {
                "value": "21.35",
                "currency": "USD"
              },
              "tax": {
                "value": "2.13",
                "currency": "USD"
              }
            },
          }
        ]
      }
    }
  ],
...

Unit IDs

A unit is considered to be an individual quantity of single line item. Each unit needs to be assigned a unit ID in the shipmentUnitIds field per line item. These unit IDs should be unique:

...
"shipmentUnitIds": [
    "unit1",
    "unit2"
],
...

In this example (with unique unit IDs) some of the units are different—for example, one of them might be free because of a "buy one get one free" deal.

In this example, the unit that the customer paid for has unit1 as its ID while the one that is free has unit2. If you need to refund the customer for one of them you can specify which one is being refunded by using the unit ID you specified in this call. In this scenario, you would specify unit2 first because that one was free.

Invoice summary

At the end of the orderinvoices.createchargeinvoice there is the summary section. This has two parts: the total and the breakdown among the entities involved. The summary is divided into the required productTotal subsection and the optional additionalChargeSummaries subsection.

Example of InvoiceSummary

...
"invoiceSummary": {
    "productTotal": {
      "pretax": {
        "value": "561.20",
        "currency": "USD"
      },
      "tax": {
        "value": "55.98",
        "currency": "USD"
      }
    },
...

Example of additionalChargeSummaries

...
    "additionalChargeSummaries": [
      {
        "type": "shipping",
        "totalAmount": {
          "pretax": {
            "value": "1.98",
            "currency": "USD"
          },
          "tax": {
            "value": "0.10",
            "currency": "USD"
          }
        }
      }
    ],
...

Example of order:get resource

{
 "kind": "content#order",
 "id": "TEST-4053-85-2702",
 "merchantId": "123205893",
 "channelType": "googleExpress",
 "lineItems": [
  {
   "id": "YQFPTREDYNCZEYE",
   "quantityOrdered": 2,
   "quantityPending": 2,
   "quantityShipped": 0,
   "quantityDelivered": 0,
   "quantityReturned": 0,
   "quantityCanceled": 0,
   "price": {
    "value": "140.00",
    "currency": "USD"
   },
   "tax": {
    "value": "14.00",
    "currency": "USD"
   },
   "shippingDetails": {
    "method": {
     "methodName": "Ground",
     "carrier": "UPS",
     "minDaysInTransit": 1,
     "maxDaysInTransit": 5
    },
    "shipByDate": "2018-10-10T22:17:33Z",
    "deliverByDate": "2018-10-13T22:17:33Z"
   },
   "returnInfo": {
    "isReturnable": true,
    "daysToReturn": 15,
    "policyUrl": "https://support.google.com/store/answer/2411741"
   },
   "product": {
    "id": "online:en:US:d3k3245",
    "offerId": "d3k3245",
    "targetCountry": "US",
    "channel": "online",
    "contentLanguage": "en",
    "price": {
     "value": "70.00",
     "currency": "USD"
    },
    "title": "Google Chromecast",
    "gtin": "00811571013579",
    "brand": "Google",
    "mpn": "H2G2-42",
    "condition": "new",
    "imageLink": "http://www.gstatic.com/shopping-content-api/product_images/chromecast.jpg",
    "shownImage": "https://encrypted-tbn1.gstatic.com/shopping?q=tbn:ANqp=CAk"
   }
  },
  {
   "id": "YYFPTREDYNCZEYE",
   "quantityOrdered": 1,
   "quantityPending": 1,
   "quantityShipped": 0,
   "quantityDelivered": 0,
   "quantityReturned": 0,
   "quantityCanceled": 0,
   "price": {
    "value": "399.85",
    "currency": "USD"
   },
   "tax": {
    "value": "39.85",
    "currency": "USD"
   },
   "shippingDetails": {
    "method": {
     "methodName": "Standard",
     "carrier": "FedEx",
     "minDaysInTransit": 3,
     "maxDaysInTransit": 6
    },
    "shipByDate": "2018-10-10T22:17:33Z",
    "deliverByDate": "2018-10-13T22:17:33Z"
   },
   "returnInfo": {
    "isReturnable": true,
    "daysToReturn": 14,
    "policyUrl": "https://support.google.com/store/answer/2411741"
   },
   "product": {
    "id": "online:en:US:df4sg53ds9",
    "offerId": "df4sg53ds9",
    "targetCountry": "US",
    "channel": "online",
    "contentLanguage": "en",
    "price": {
     "value": "399.85",
     "currency": "USD"
    },
    "title": "Nexus 9",
    "gtin": "00821793042684",
    "brand": "HTC",
    "mpn": "99HZF001-00",
    "condition": "new",
    "itemGroupId": "123",
    "imageLink": "http://www.gstatic.com/shopping-content-api/product_images/nexus_9.jpg",
    "shownImage": "https://encrypted-tbn1.gstatic.com/shopping?q=tbn:AN&usqp=CAk",
    "variantAttributes": [
     {
      "dimension": "color",
      "value": "lunar white"
     },
     {
      "dimension": "memory",
      "value": "16 GB"
     },
     {
      "dimension": "connectivity",
      "value": "Wi-Fi only"
     }
    ]
   }
  }
 ],
 "status": "pendingShipment",
 "paymentStatus": "paymentSecured",
 "acknowledged": false,
 "shippingOption": "standard",
 "placedDate": "2018-10-24T19:22:38Z",
 "deliveryDetails": {
  "address": {
   "recipientName": "Pam Beesly",
   "streetAddress": [
    "1600 Amphitheatre Parkway",
    "Building 48 1N1C"
   ],
   "locality": "Mountain View",
   "region": "CA",
   "country": "US",
   "postalCode": "94043",
   "fullAddress": [
    "Pam Beesly",
    "1600 Amphitheatre Parkway",
    "Building 48 1N1C",
    "Mountain View, CA 94043",
    "United States"
   ]
  },
  "phoneNumber": "+1 650-555-0000"
 },
 "customer": {
  "fullName": "Pam Beesly",
  "email": "pam@example.com",
  "marketingRightsInfo": {
   "explicitMarketingPreference": "denied",
   "lastUpdatedTimestamp": "2018-10-01T22:17:33Z"
  }
 },
 "paymentMethod": {
  "type": "AMEX",
  "lastFourDigits": "5678",
  "billingAddress": {
   "recipientName": "Jim Halpert",
   "locality": "Scranton",
   "region": "PA",
   "country": "US",
   "postalCode": "18501",
   "fullAddress": [
    "Jim Halpert",
    "Scranton, PA 18501",
    "United States"
   ]
  },
  "phoneNumber": "+1 412-345-6700",
  "expirationMonth": 9,
  "expirationYear": 2020
 },
 "shippingCost": {
  "value": "21.35",
  "currency": "USD"
 },
 "shippingCostTax": {
  "value": "2.13",
  "currency": "USD"
 },
 "netAmount": {
  "value": "617.18",
  "currency": "USD"
 }
}

orderinvoices.createrefundinvoice

POST https://shoppingcontent.googleapis.com/content/v2.1/merchantId/orderinvoices/orderId/createRefundInvoice
POST https://shoppingcontent.googleapis.com/content/v2.1sandbox/merchantId/orderinvoices/createRefundInvoice

You can use orderinvoices.createrefundinvoice to offer customers a complete or partial refund, or complete a return for an order. This can be, for example, because the customer requested a refund or return, or because you wanted to give them a discount or refund for any other reason. For refund requests initiated through Google, we recommend using orderreturns.process (v2.1 only), which is simpler to use than orderinvoices.createchargeinvoice.

Example orderinvoices.createrefundinvoice body

{
  "invoiceId": "invoice2",
  "operationId": "refund1",
  "returnOption": {  // Item is being returned as well as refunded.
    "reason": "customerDiscretionaryReturn",
    "description": "Didn't like it"
  },
  "shipmentInvoices": [
    {
      "shipmentGroupId": "shipmentgroup1",  // Matches ID defined in shiplineitems.
      "lineItemInvoices": [
        {
          "productId": "online:en:US:d3k3245",
          "shipmentUnitIds": [
            "unit1",
            "unit2"
          ],
          "unitInvoice": {
            "unitPricePretax": {
              "value": "-140",  // Negative because line item is being refunded.
              "currency": "USD"
            },
            "unitPriceTaxes": [
              {
                "taxType": "sales",
                "taxAmount": {
                  "value": "-14",
                  "currency": "USD"
                }
              }
            ]
          }
        },
        {
          "productId": "online:en:US:df4sg53ds9",
          "shipmentUnitIds": [
            "unit1"
          ],
          "unitInvoice": {
            "unitPricePretax": {
              "value": "-399.85",
              "currency": "USD"
            },
            "unitPriceTaxes": [
              {
                "taxType": "sales",
                "taxAmount": {
                  "value": "-39.85",
                  "currency": "USD"
                }
              }
            ],
            "additionalCharges": [
              {
                "type": "shipping",
                "additionalChargeAmount": {
                  "pretax": {
                    "value": "-21.35",
                    "currency": "USD"
                  },
                  "tax": {
                    "value": "-2.13",
                    "currency": "USD"
                  }
                }
              }
            ]
          }
        }
      ],
      "invoiceSummary": {
        "productTotal": {
          "pretax": {
            "value": "-561.20",
            "currency": "USD"
          },
          "tax": {
            "value": "-55.98",
            "currency": "USD"
          }
        }
      }
    }
  ]
}

This example is a literal inverse of the charge invoice shown earlier, refunding it completely. Note that you could refund it partially.

Same fields as orderinvoices.createchargeinvoice

You use the same fields you set up in orderinvoices.createchargeinvoice to execute a detailed refund that breaks down the refund amounts by product cost, taxes, and fees on a line item level. Essentially, orderinvoices.createrefundinvoice is orderinvoices.createchargeinvoice in reverse.

You cannot use orderinvoices.createrefundinvoice without having used orderinvoices.createchargeinvoice first.

Refund only or refund and return

You have the option to do a refund only or return by using the refundOnlyOption or returnOption. You can only use one of these, and you must use one or the other.

Refund without return

...
"refundOnlyOption": {
  "reason": "adjustment",
  "description": "Missed Shipping Date"
},
...

Refund with return

...
"returnOption": {
  "reason": "customerDiscretionaryReturn",
  "description": "Ordered By Mistake"
},
...

Shipment group and unit IDs

To reference the orderinvoices.createrefundinvoice you need to specify the shipmentGroupId and shipmentUnitIds that you specified in the original orderinvoices.createchargeinvoice call.

Example shipmentGroupId

...
"shipmentGroupId": "shipmentgroup1",
...

For each set of unit IDs within a line item you need to specify the pre-tax price, the taxes and fees, and the additional charges. If the values for one unit are different from the other units in that line item you can separate them; if they are the same you can keep them together.

Example shipmentUnitIds

...
"shipmentUnitIds": [
    "unit1",
    "unit2"
],
...

For a total refund the values will all be the same as in the charge invoice created earlier. For partial refund the values would have to be less than or equal to the values in the charge invoice—you cannot give back more than they paid originally.

Example of productTotal section

...
"invoiceSummary": {
  "productTotal": {
    "pretax": {
      "value": "-561.20",
      "currency": "USD"
    },
    "tax": {
      "value": "-55.98",
      "currency": "USD"
    }
  },
...

Finally, you need to specify the summary.

Example summary

...
"invoiceSummary": {
  "productTotal": {
    "pretax": {
      "value": "-561.20",
      "currency": "USD"
    },
    "tax": {
      "value": "-55.98",
      "currency": "USD"
    }
  }
}
...

Test the Order Invoices API

Test orderinvoices.createchargeinvoice

Testing create test order is somewhat involved. Let's start with an overview.

  1. Create a test order.

    1. Get a template json body.
    2. Add "enableOrderinvoices": true.
    3. Call "create test order".
  2. Advance the test order.

  3. Call shiplineitem on the test order.

  4. All orderinvoices.createchargeinvoice on the test order.

    1. Construct the body.
    2. Make the call.

Sample test order

Since the whole rest of this document is devoted to explaining how this API works, here we'll just give you a series of concrete example for testing purposes.

Create test order

{
  "testOrder": {
    "enableOrderinvoices": true,
    "customer": {
      "fullName": "Pam Beesly",
      "email": "pam@example.com",
      "explicitMarketingPreference": false,
      "marketingRightsInfo": {
        "explicitMarketingPreference": "denied",
        "lastUpdatedTimestamp": "2018-10-01T22:17:33Z"
      }
    },
    "lineItems": [{
        "product": {
          "offerId": "d3k3245",
          "channel": "online",
          "targetCountry": "US",
          "contentLanguage": "en",
          "title": "Google Chromecast",
          "price": {
            "value": "70.00",
            "currency": "USD"
          },
          "condition": "new",
          "gtin": "00811571013579",
          "brand": "Google",
          "mpn": "H2G2-42",
          "imageLink": "http://www.gstatic.com/shopping-content-api/product_images/chromecast.jpg"
        },
        "quantityOrdered": 2,
        "unitTax": {
          "value": "7.00",
          "currency": "USD"
        },
        "shippingDetails": {
          "method": {
            "methodName": "Ground",
            "carrier": "UPS",
            "minDaysInTransit": 1,
            "maxDaysInTransit": 5
          },
          "shipByDate": "2018-10-10T22:17:33Z",
          "deliverByDate": "2018-10-13T22:17:33Z"
        },
        "returnInfo": {
          "isReturnable": true,
          "daysToReturn": 15,
          "policyUrl": "https://support.google.com/store/answer/2411741"
        }
      },
      {
        "product": {
          "offerId": "df4sg53ds9",
          "channel": "online",
          "targetCountry": "US",
          "contentLanguage": "en",
          "title": "Nexus 9",
          "price": {
            "value": "399.85",
            "currency": "USD"
          },
          "condition": "new",
          "gtin": "00821793042684",
          "brand": "HTC",
          "mpn": "99HZF001-00",
          "variantAttributes": [{
              "dimension": "color",
              "value": "lunar white"
            },
            {
              "dimension": "memory",
              "value": "16 GB"
            },
            {
              "dimension": "connectivity",
              "value": "Wi-Fi only"
            }
          ],
          "itemGroupId": "123",
          "imageLink": "http://www.gstatic.com/shopping-content-api/product_images/nexus_9.jpg"
        },
        "quantityOrdered": 1,
        "unitTax": {
          "value": "39.85",
          "currency": "USD"
        },
        "shippingDetails": {
          "method": {
            "methodName": "Standard",
            "carrier": "FedEx",
            "minDaysInTransit": 3,
            "maxDaysInTransit": 6
          },
          "shipByDate": "2018-10-10T22:17:33Z",
          "deliverByDate": "2018-10-13T22:17:33Z"
        },
        "returnInfo": {
          "isReturnable": true,
          "daysToReturn": 14,
          "policyUrl": "https://support.google.com/store/answer/2411741"
        }
      }
    ],
    "predefinedDeliveryAddress": "pam",
    "paymentMethod": {
      "type": "AMEX",
      "lastFourDigits": "5678",
      "predefinedBillingAddress": "jim",
      "expirationMonth": 9,
      "expirationYear": 2020
    },
    "shippingCost": {
      "value": "21.35",
      "currency": "USD"
    },
    "shippingCostTax": {
      "value": "2.13",
      "currency": "USD"
    },
    "shippingOption": "standard"
  }
}

Advance test order

Call orders.hiplineitems

{
  "operationId": "dave2",
  "lineItems": [{
      "productId": "online:en:US:d3k3245",
      "quantity": 2
    },
    {
      "productId": "online:en:US:df4sg53ds9",
      "quantity": 1
    }
  ],
  "shipmentGroupId": "shipmentgroup1",
  "shipmentInfos": [{
    "shipmentId": "SHIPMENT1",
    "carrier": "UPS",
    "trackingId": "1234567890"
  }]
}
POST https://shoppingcontent.googleapis.com/content/v2.1/merchantId/orders/orderId/shipLineItems

Call orderinvoices.createchargeinvoice

Please see the examples elsewhere in this document.

Test orderinvoices.createrefundinvoice

Using the order we already created, you'll now create an order return for it.

  1. Mark order delivered.
  2. Mark order returned.
  3. Call orderinvoices.createrefundinvoice on order.

Mark order delivered

{
  "operationId": "dave3",
  "status": "delivered",
  "shipmentId": "SHIPMENT1"
}
POST https://shoppingcontent.googleapis.com/content/v2.1/merchantId/orders/orderId/updateShipment

Mark order returned

{
  "items": [
    {
      "lineItemId": "<lineitem>",
      "quantity": <quantity>
    }
  ]
}

POST https://shoppingcontent.googleapis.com/content/v2.1/merchantId/orders/orderId/testreturn

Call orderinvoices.createrefundinvoice

Please see examples in the body of this document.