Returns Experience Integration Guide

This guide provides detailed integration guidance and includes examples across common use cases within Optoro’s Returns Experience Product and associated features.

Interfaces

This section provides an overview of each application interface message and its purpose.

Enables Returns Portal and Express Returns

Returns Portal Orders

APIs used to publish order history and order events to Optoro which enables return initiation (creation of an RMA). Generally from your ecommerce platform to Optoro.

POST

Customer → Optoro

Return Merchandise Authorizations (RMAs)

Webhooks used to update the customer with RMAs and RMA status changes to enable tracking and refunding. Generally from Optoro to your Order Management System (OMS).

POST

Optoro → Customer

Enables Exchanges

Exchange Variants

API requests used to receive product variant availability to offer exchange options to the shopper. Generally from Optoro to your ecommerce platform.

GET

Optoro → Customer

Exchange Orders

APIs used to place an exchange order in the customer’s ecommerce Platform. Generally from Optoro to your ecommerce platform.

POST

Optoro → Customer

Returns Portal Orders

The Returns Portal Orders API is used to inform Optoro of order updates from your Order Management System(OMS)/ecommerce Platform. Customers utilize the Returns Portal Order API to power the online returns portal experience for shoppers.

Integration:

  • Customer: Your Order Management System or ecommerce Platform POSTs the Returns Portal Orders messages to Optoro.
  • Optoro: Successful receipt of the Returns Portal Orders message will store the order in the secured Optoro repository. The orders in this repository are what shoppers see when they initiate a return.

When it is used:

  • You post a Returns Portal Orders message to Optoro with the full snapshot of the order at the first shipped event of the order. At initial implementation, orders for the previous six months (usually) are posted and then orders are posted as they ship.
  • You post a Returns Portal Orders message to Optoro with the full snapshot of the order when order lifecycle events occur. This includes: fulfillments, transactions, adjustments, and order line item modifications. Updates should be as close to real time as possible.
  • You post a Returns Portal Orders message to Optoro when the order and/or items within the order are refunded.

What information is included:

  • orders object – information about the order
  • items object – an array with information about each item in the order
  • customer object – information about the shopper including shipping and billing addresses
  • refunds object – information about any refunds issued against this order

Format:

POST https://orders.{{url}}/returns_portal_orders where the URL for your application is provided to you by Optoro. Example: POST https://orders.optiturn.com/returns_portal_orders

Response: 200 Success

See Returns Portal Orders API specification for more details.

Return Merchandise Authorizations (RMAs)

The RMAs webhook is used to keep you current with all events relating to an RMA initiated in Optoro’s Return Portal.

Integration:

  • Optoro: Optoro POSTS the RMAs message to your Order Management System (OMS) using the URL and endpoint you provide.
  • Customer: Your OMS uses the information provided in the RMAs message to enable refunds and returns tracking.

When it is used:

  • Optoro posts an RMAs message to you when the shopper initiates a return.
  • Optoro posts an RMAs message to you when carrier tracking details are provided (when applicable).
  • Optoro posts an RMAs message to you when the carrier receives and scans the return.
  • Optoro posts an RMAs message when the shopper drops off the return at a drop-off location or when a pick-up partner picks up the return from the shopper.
  • Optoro posts an RMAs message when the item is received (and ready for refund) when you also use Optoro’s Returns Management solution.
  • Optoro posts an RMAs message to you after you update the order with refund details in the Refunds object of the Returns Portal Order API.

What information is included:

  • items object – an array with details for all items included in the shopper’s return. Some of those fields are:
    • order_identifier - Used to uniquely identify the order associated with the RMA
    • order_line_item_identifier - The line item within the order being returned
    • refund_type - Identifies if it is a refund or exchange transaction
    • package_tracking_status - Identifies the status of the return item which will vary based on the chosen return_method
  • When applicable, includes values for:
    • tracking_number - Carrier tracking number (based on return method)
    • original_order_identifier - The original order when this is related to an exchange order
    • exchange_order_identifier - The order number of the exchange order when a return item is exchanged
    • receiving_status - populated when you use the Returns Management solution to handle your returned items
  • return_method – a field that identifies the return method chosen by the shopper. The values for package tracking status will vary based on the return method.

Format:

POST https://{{yoururl}}/{{yourendpoint}} where you provide the URL and the endpoint to Optoro. Example: POST https://customer.com/rmas

Response: 200 Success

See RMAs API specification for more details.

Exchange Variants

The Exchange Variants API is what enables Even Exchanges. It is used to request a list of available product variants, typically items of the same style number, from your ecommerce platform when the shopper will be offered an opportunity to exchange a return item.

Integration:

  • Optoro: Optoro sends an Exchange Variants GET message to your ecommerce Platform (or directly to your OMS if desired) using the URL and endpoint you provide.
  • Customer: Your ecommerce platform returns a list of exchange options identified by the parameter provided on the Exchange Variants GET message.

When it is used:

  • Optoro sends an Exchange Variants GET message to you when the shopper chooses a return reason that prompts the returns portal to show exchange options for an item that has an associated variant identifier.

What information is included:

  • variant_identifier – the variant identifier code (sometimes referred to as the parent sku) provided with this item in the original Returns Portal Order message is sent as the parameter on the Exchange Variants GET message.

What information is returned:

  • Variants object – based on the variant_identifier provided on the Exchange Variants GET message, you return an array of relevant exchange options that include attributes describing the variants and identifying the price and quantities.

Format:

GET https://{{yoururl}}/sku/{{variant_identifier}}/{{yourendpoint}} where you provide the URL and the endpoint to Optoro and variant_identifier is a required parameter. Example: GET https://customer.com/sku/97045/exchange_variants

Response: 200 A list of product variants

See Variants API specification for more details.

Exchange Orders

The Exchange Orders API is used to place an order in your ecommerce platform when the shopper has chosen to exchange for a replacement item or receive their refund via a gift card.

Integration:

  • Optoro: Optoro POSTS an Exchange Orders message to your ecommerce Platform (or directly to your OMS if desired) using the URL and endpoint you provide.
  • Customer: Your ecommerce platform handles the Exchange Order as a new order, calculates all tax and shipping, and processes the order for fulfillment.

When it is used:

  • Optoro POSTS an Exchange Orders message to you when the shopper has confirmed an exchange, selected a gift card refund, or both.

What information is included:

  • items object – an array with information about each item in the exchange order
  • customer object – information about the shopper
  • payment – an identifier used to report and reconcile payments of exchange orders

Format:

POST https://{{yoururl}}/{{yourendpoint}} where you provide the URL and the endpoint to Optoro. Example: POST https://customer.com/exchange_orders

Response: 200 Success

See Exchange Orders API specification for more details.

Common Use Cases

The purpose of this section is to present a number of common scenarios, outline the required API calls, provide guidance on the behavior of specific attributes within those API calls, and display sample payloads across the four Returns Experience interfaces. This section consists of three subsections:

  • Mailback Returns
  • Express Returns
  • Tags

The Mailback and Express Returns subsections have scenarios for each return method that include different order types:

  • Single or multi-line
  • Full Refund or Exchanges (Even and Uneven)
  • Partial Returns and Partial Exchanges
  • Full and partial cancellations
  • Cancel the return

The Tags subsection describes how to populate the Returns Portal Orders API to flag items that have specific return conditions like Buy Online Pickup In Store, Final Sale, etc.

Mailback

Single-Line, Full Refund, Mailback

This scenario is a full refund of a single line order where the retailer refunds at carrier scan. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro Returns Portal. They decide to return the full order, which is 4 units of one line and to return via the mailback option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. 2. POST RMA
  • When the carrier responds with the tracking number and package status, the RMA will be updated and sent out again. This should happen within a few seconds of the initial creation RMA. 3. POST RMA
  • The shopper then drops their package off to the carrier. This moves the package status to "TRANSIT" and triggers a POST RMA to be sent. 4. POST RMA
  • The brand in this scenario refunds at carrier scan so when it receives the POST RMA with the "TRANSIT" package status and "return_method": "mail-back" , it generates the refund. With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 5. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should be closed there as well. 6. POST RMA

Sample payloads for this scenario:

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            "identifier": "ORD1234567", // identifier is the order identifier used by the customers internal ecomm systems
            "raw_status": "fulfilled",
            "status": "Shipped", // status can be sent as Created, Shipped, or Cancelled
            "total_amount_cents": 52224, // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "product_amount_cents": 51200, // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "tax_amount_cents": 1024, // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00", // created_at should be the tiime the order was created in the Order Management System
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  "identifier": "1", // identifier is the forward order lines identifier
                  "sku": "sku1234",
                  "upc": "1234",
                  "quantity": 4, // The quantity is the total quantity on the order-line
                  "quantity_shipped": 4, // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_canceled": 0, // The quantity_canceled is the total quantity of cancelled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "tracking_number": "1Z9999999999999999",
                  "shipped_date": "2023-01-23T13:37:19+00:00", // shipped_date can be used to mark the start of the return window
                  "product_identifier": "32174", // product_identifier is the customer's unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "variant_identifier": "96027", // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "title": "Black T-Shirt",
                  "tags": [],
                  "product_amount_cents": 51200, // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "tax_amount_cents": 1024, // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "discount_amount_cents": 0,
                  "unit_price_amount_cents": 12800, // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "image_url": "https://media.media.com/media/123.jpg",
                  "weight": 1.12 // weight is needed for determining ER eligibility if catalog is not provided
               }
            ],
            "customer": {
               "identifier": "219299", // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "transactions": [], // The transactions object needs to be sent but only as an empty array like below
            "refunds": [], // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "discounts": [] // discounts object needs to be sent but only as an empty array like below
         }
      ]
   }
}'
2. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
   "rma_identifier": "8b3P5rCjHW", // rma_identifier is an Optoro generate value
   "status": "CREATED", // Status should only be looked at if you are using managed services RM
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   "items": [ // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null,
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": null, // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "package_tracking_status": null,
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null,
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": null, // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "package_tracking_status": null,
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null,
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": null, // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "package_tracking_status": null,
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null,
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": null, // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "package_tracking_status": null,
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      }
   ],
   "return_method": "mail-back", // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_shipping_cost_cents": 0,
   "gift_refund_only": true, // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "giftee_email": "email@email.com" // giftee_email will only be sent if gift_refund_only is true
}'
3. POST RMA - RMA Tracking Number Added
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
   "rma_identifier": "8b3P5rCjHW", // rma_identifier is an Optoro generate value
   "status": "CREATED", // Status should only be looked at if you are using managed services RM
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:12Z",
   "items": [ // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      }
   ],
   "return_method": "mail-back", // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_shipping_cost_cents": 0,
   "gift_refund_only": true, // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "giftee_email": "email@email.com" // giftee_email will only be sent if gift_refund_only is true
}'
4. POST RMA - RMA Carrier Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
   "rma_identifier": "8b3P5rCjHW", // rma_identifier is an Optoro generate value
   "status": "CREATED", // Status should only be looked at if you are using managed services RM
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:40:22Z",
   "items": [ // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "TRANSIT", // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "TRANSIT", // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "TRANSIT", // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "TRANSIT", // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      }
   ],
   "return_method": "mail-back", // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_shipping_cost_cents": 0,
   "gift_refund_only": true, // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "giftee_email": "email@email.com" // giftee_email will only be sent if gift_refund_only is true
}'
5. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            "identifier": "ORD1234567", // identifier is the order identifier used by the customers internal ecomm systems
            "raw_status": "Refunded", // raw_status is the status of the order in external systems, typically OMS status
             "status": "Shipped", // Status shoould be sent as Shipped since the full order has been shipped in this scenario
            "total_amount_cents": 52224, // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "product_amount_cents": 51200, // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "tax_amount_cents": 1024, // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  "identifier": "1", // identifier is the forward order lines identifier
                  "sku": "sku1234",
                  "upc": "1234",
                  "quantity": 4, // The quantity is the total quantity on the order-line
                  "quantity_shipped": 4, // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_canceled": 0, // The quantity_canceled is the total quantity of cancelled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "tracking_number": "1Z9999999999999999",
                  "shipped_date": "2023-01-23T13:37:19+00:00", // shipped_date can be used to mark the start of the return window
                  "product_identifier": "32174", // product_identifier is the customer's unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "variant_identifier": "96027", // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "title": "Black T-Shirt",
                  "tags": [],
                  "product_amount_cents": 51200, // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "tax_amount_cents": 1024, // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "discount_amount_cents": 0,
                  "unit_price_amount_cents": 12800, // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "image_url": "https://media.media.com/media/123.jpg",
                  "weight": 1.12 // weight is needed for determining ER eligibility if catalog is not provided
               }
            ],
            "customer": {
               "identifier": "219299", // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "transactions": [], // The transactions object needs to be sent but only as an empty array like below
            "refunds": [
               {
               "identifier": "RET202301280000001", // The identifier in the header of the refund object needs to be unique across all refunds
               "total_refund_amount_cents": 52224, //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "refund_line_items": [ // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full refund so all units are included.
                  {
                  "identifier": "RET202301280000001_1", // The identifier in the refund_line_items object needs to be unique across all refunds
                  "quantity": 4, // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "order_item_identifier": "1" // order_item_identifier should match the identifier field of the sku in the items array
                  }
               ],
               "note": "Returned", // The note is not required and only used for data purposes
               "created_at": "2023-01-28T19:42:49.23Z", // created_at needs to be sent with a date in the future.
               "rma_identifier": "8b3P5rCjHW" // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               }
            ],
            "discounts": []
         }
      ]
   }
}'
6. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
   "rma_identifier": "8b3P5rCjHW", // rma_identifier is an Optoro generate value
   "status": "REFUNDED", // Status should only be looked at if you are using managed services RM
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   "items": [ // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "TRANSIT", // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "TRANSIT", // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "TRANSIT", // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      },
      {
         "order_line_item_identifier": "1", // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_identifier": "ORD1234567",
         "exchange_order_identifier": null, // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "original_order_identifier": null, // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "return_reason": "Changed Mind",
         "is_exchange": false, // is_exchange indicates whether the RMA item belongs to an exchange order
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "TRANSIT", // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "receiving_status": "PENDING", // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "refund_financials": { // The refund_financials object should be used for determing how much to refund only for even exchanges.
            "estimated_refund_amount_cents": 13056, // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "optoro_refund_amount_cents": 0, // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "shopper_refund_amount_cents": 13056 // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
         },
         "refund_type": "REFUND" // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
      }
   ],
   "return_method": "mail-back", // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_shipping_cost_cents": 0,
   "gift_refund_only": true, // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "giftee_email": "email@email.com" // giftee_email will only be sent if gift_refund_only is true
}'

Multi-Line, Full Refund, Mailback

The scenario shown here is for a full refund of a multi-line order where the brand refunds at carrier scan. The full flow is described below followed by sample payloads.

  • Partial order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Remainder of the order is shipped, triggering the complete order to be pushed to Optoro through the Returns Portal Order API. 2. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and 3 units of another. They choose to return via the mailback option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. 3. POST RMA
  • When the carrier responds with the tracking number and package status, the RMA will be updated and sent out again. This should happen within a few seconds of the initial creation RMA. 4. POST RMA
  • The shopper then drops their package off to the carrier. This moves the package status to "TRANSIT" and triggers a POST RMA to be sent. 5. POST RMA
  • The brand in this scenario refunds at carrier scan so when it receives the POST RMA with the "TRANSIT" package status and "return_method": "mail-back" , it generates the refund. With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 6. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 7. POST RMA

Sample payloads for this scenario:

1. POST Returns Portal Order - Create Returns Portal Order - Shipment 1
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            "identifier": "ORD1234567", // identifier is the order identifier used by the customers internal ecomm systems
            "raw_status": "Partially Fulfilled", // raw_status is the status of the order in external systems, typically OMS status
            "status": "Created", // status can be sent as Created, Shipped, or Cancelled. Since this scenario has the order shipped in two separated shipments the first message will be sent with Created status
            "total_amount_cents": 52224, // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "product_amount_cents": 51200, // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "tax_amount_cents": 1024, // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  "identifier": "1", // identifier is the forward order lines identifier
                  "sku": "sku1234",
                  "quantity": 4, // The quantity is the total quantity on the order-line
                  "quantity_shipped": 4, // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment of this line so the quantity_shipped is equal to the quantity
                  "quantity_canceled": 0, // The quantity_canceled is the total quantity of cancelled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "tracking_number": "1Z9999999999999999",
                  "shipped_date": "2023-01-23T13:37:19+00:00", // shipped_date can be used to mark the start of the return window
                  "product_identifier": "32174", // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "variant_identifier": "96027", // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "title": "Black T-Shirt",
                  "tags": [],
                  "product_amount_cents": 51200, // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "tax_amount_cents": 1024, // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "discount_amount_cents": 0,
                  "unit_price_amount_cents": 12800, // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "image_url": "https://media.media.com/media/123.jpg",
                  "weight": 1.12 // weight is needed for determining ER eligibility if catalog is not provided
               },
               {
                  "identifier": "2", // identifier is the forward order lines identifier
                  "sku": "sku1235",
                  "quantity": 3, // The quantity is the total quantity on the order-line
                  "quantity_shipped": 0, // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a split shipment where this line is shipped after the first line, thus the initial Returns Portal Orders API will have quantity_shipped set to 0
                  "quantity_canceled": 0, // The quantity_canceled is the total quantity of cancelled units on the order-line.  This scenario is a split shipment where this line is shipped after the first line but the line is to be fully shipped in this scenario so quantity_canceled is set to 0.
                  "product_identifier": "32175", // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "variant_identifier": "96028", // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "title": "White T-Shirt",
                  "tags": [],
                  "product_amount_cents": 0, // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "tax_amount_cents": 0, // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "discount_amount_cents": 0,
                  "unit_price_amount_cents": 10000, // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "image_url": "https://media.media.com/media/124.jpg",
                  "weight": 1.12 // weight is needed for determining ER eligibility if catalog is not provided
               }
            ],
            "customer": {
               "identifier": "219299", // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "transactions": [], // The transactions object needs to be sent but only as an empty array like below
            "refunds": [], // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "discounts": [] // discounts object needs to be sent but only as an empty array like below
         }
      ]
   }
}'
2. POST Returns Portal Order - Create Returns Portal Order - Shipment 2
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Cancelled. Since this scenario has the order shipped in two separated shipments the second message will be sent with Shipped status now that both lines are shipped
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 85224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 81200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 4024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T17:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment of this line so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of cancelled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a split shipment where this line is shipped after the first line. This second Returns Portal Orders API will have quantity_shipped set to the quantity since now this line is shipped.
                  "quantity_shipped": 3,
                  // status can be sent as Created, Shipped, Cancelled, or Refunded. This scenario is a split shipment where this line is shipped after the first line. This second Returns Portal Orders API will have status set to Shipped since now this line is shipped.
                  // The quantity_canceled is the total quantity of cancelled units on the order-line. This scenario is a split shipment where this line is shipped after the first line. Since this line is fully shipped without any cancelled units, quantity_canceled is set to 0.
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999981",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T17:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 3000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/124.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
3. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units of one line and 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the tracking_number and package_tracking_status will be null for mail-back RMA'\''s
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the tracking_number and package_tracking_status will be null for mail-back RMA'\''s
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the tracking_number and package_tracking_status will be null for mail-back RMA'\''s
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the tracking_number and package_tracking_status will be null for mail-back RMA'\''s
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Upon initial RMA creation the tracking_number and package_tracking_status will be null for mail-back RMA'\''s
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Upon initial RMA creation the tracking_number and package_tracking_status will be null for mail-back RMA'\''s
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Upon initial RMA creation the tracking_number and package_tracking_status will be null for mail-back RMA'\''s
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
4. POST RMA - RMA Tracking Number Added
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units of one line and 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
5. POST RMA - RMA Carrier Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:40:22Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units of one line and 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
6. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
             // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of cancelled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of cancelled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999981",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T17:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 3000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/124.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 85224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full refund so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  },
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_2",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 3,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "2"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
7. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned.  Since this scenario is a refund of 4 units of one line and 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Single-Line, Even Exchange, Mailback

The scenario shown here is for a full even exchange of a single line order where the brand refunds at carrier scan. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and they choose a reason code that prompts RX to show exchange options.
  • RX takes the original item's variant identifier and calls the variants API to find the possible items to show the shopper for the exchange. 2. GET Exchange Variants
  • The shopper chooses the exchange item they want and decides to return the original units via the mail back option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. 3. POST RMA
  • At the same time as the initial RMA creation, an Even Exchange message will be posted out from RX. This will tell the forward order system that they need to ship the exchange item to the shopper. The exchange order will have references to the RMA the exchange was created with as well as the original order number for the forward order the exchange was created against. This is in the order_identifier field. 4. POST Exchange Order
  • When the carrier responds with the tracking number and package status, the RMA will be updated and sent out again. This should happen within a few seconds of the initial creation RMA. 5. POST RMA
  • The shopper then drops their package off to the carrier. This moves the package status to "TRANSIT" and triggers a POST RMA to be sent. 6. POST RMA
  • The brand in this scenario refunds at carrier scan so when it receives the POST RMA with the "TRANSIT" package status and "return_method": "mail-back" , it generates the refund. Given this is an even exchange, no money is actually charged against the shopper. This can be seen by the refund_financials object where the shopper_refund_amount_cents is 0.
  • When the refund is generated, it sends back to Optoro a Returns Portal Order message with the refund details. 7. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 8. POST RMA

Sample payloads for this scenario:

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Cancelled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and exchange so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of cancelled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. GET Exchange Variants - Get Exchange Variants
RequestResponse
Copy
Copied
curl --location -g 'http://{{customerurl}}/sku/96027/variants' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'
Copy
Copied
{
  "variants": [
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "XL"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 10,
      "sku": "sku1236",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12346"
    },
    {
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "S"
        }
      ],
      "quantity_in_stock": 15,
      "sku": "sku1237",
      "title": "Blue T-Shirt",
      "unit_price_amount_cents": 12800,
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12347"
    }
  ]
}
3. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
4. POST Exchange Order - Even Exchange Created
RequestResponse
Copy
Copied
curl --location -g 'https://{{customerurl}}/orders' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "currency": "USD",
    "note": "order note",
    // rma_identifier is taken from the RMA created when the exchange was created
    "rma_identifier": "8b3P5rCjHW",
    // original_order_id is taken from return portal order for which the exchange was created against
    "original_order_id": "ORD1234567",
    "is_gift": false,
    // This scenario is an exchange of a full line of an order. There is one item object in the items array with a quantity of 4 as that what was returned.
    "items": [
        {
            // The sku will be different in the even exchange api as to what was in the RPO or RMA API as the exchange will be for a new item altogether, even if it'\''s the same style/variant.
            "sku": "sku1236",
            // quantity is quantity being exchanged
            "quantity": 4,
            "title": "Blue T-Shirt",
            "unit_price_amount_cents": 12800,
            // product_amount_cents is unit_price_amount_cents * quantity
            "product_amount_cents": 51200,
            "discount_amount_cents": 0,
            "tax_amount_cents": 1024,
            "product_identifier": "32175",
            "variant_identifier": "96027"
        }
    ],
    "customer": {
        // If there is no customer identifier it is recommended to send the shoppers email as the identifier
        "identifier": "219299",
        "first_name": "Ben",
        "last_name": "Wallace",
        "email": "BWallace@gmail.com",
        "phone": "3017607003"
    },
    "shipping_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the shipping_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "billing_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the billing_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "payment": {
        // This is an Optoro generated number for the payment of the exchange order
        "transaction_id": "8ef05fb8-283e-4edd-a3d7-47f9fe520cfe"
    }
}'
Copy
Copied
{
  // order_identifier is the order identifier given by the order capture system
  "order_identifier": "EXCH12345",
  // total_amount_cents is the updated total of the exchange order after re-pricing by the order capture system
  "total_amount_cents": 52224,
  // product_amount_cents is the updated product price of the exchange order after re-pricing by the order capture system
  "product_amount_cents": 51200,
  // tax_amount_cents is the updated tax amount of the exchange order after re-pricing by the order capture system
  "tax_amount_cents": 1024
}
5. POST RMA - RMA Tracking Number Added
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
6. POST RMA - RMA Carrier Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:40:22Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
7. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and exchange so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of cancelled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 52224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full exchange so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
8. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Single-Line, Even Exchange with all_size, Mailback

The scenario shown here is for a full even exchange of a single line order where the brand refunds at carrier scan. This is with an order that has an item with multiple size differentiators, meaning in the variants response an attribute called all_size is sent that describes all the size attributes. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and they choose a reason code that prompts RX to show exchange options.
  • RX takes the original item's variant identifier and calls the variants API to find the possible items to show the shopper for the exchange. In the response to the variants API, one of the attributes will be all_size . This describes all of the item's sizes in a single field. 2. GET Exchange Variants
  • The shopper chooses the exchange item they want and decides to return the original units via the mail back option.
  • When the shopper confirms the return in the portal, a RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. 3. POST RMA
  • At the same time as the initial RMA creation, an Even Exchange message will be posted out from RX. This will tell the forward order system that they need to ship the exchange item to the shopper. The exchange order will have references to the RMA the exchange was created with as well as the original order number for the forward order the exchange was created against. This is in the order_identifier field. 4. POST Exchange Order
  • When the carrier responds with the tracking number and package status, the RMA will be updated and sent out again. This should happen within a few seconds of the initial creation RMA. 5. POST RMA
  • The shopper then drops their package off to the carrier. This moves the package status to "TRANSIT" and triggers a POST RMA to be sent. 6. POST RMA
  • The brand in this scenario refunds at carrier scan so when it receives the POST RMA with the "TRANSIT" package status and "return_method": "mail-back" , it generates the refund. Given this is an even exchange, no money is actually charged against the shopper. This can be seen by the refund_financials object where the shopper_refund_amount_cents is 0.
  • With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 7. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 8. POST RMA

Sample payloads for this scenario:

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and exchange so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. GET Exchange Variants - Get Exchange Variants
RequestResponse
Copy
Copied
curl --location -g 'http://{{customerurl}}/sku/96027/variants' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'
Copy
Copied
{
  "variants": [
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "XL"
        },
        {
          "name": "Variant",
          "value": "PETITE"
        },
        {
          "name": "Length",
          "value": "32"
        },
        {
          "name": "all_size",
          // The value for the all_size attribute should be the different size values with '|' as a delimiter. In this instanze the item can be described by size, variant, and length so they are all included in the all_size attribute of the response.
          "value": "XL | PETITE | 32"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 10,
      "sku": "sku1236",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12346"
    },
    {
      "attributes": [
        // attributes array clarifies the type of variant the sku is, the name specifies what type of variant the attribute describes. The all_size attribute is needed if there are more than one size differentiations, such as Variant or Length.
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "S"
        },
        {
          "name": "Variant",
          "value": "PETITE"
        },
        {
          "name": "Length",
          "value": "32"
        },
        {
          "name": "all_size",
          // The value for the all_size attribute should be the different size values with '|' as a delimiter. In this instanze the item can be described by size, variant, and length so they are all included in the all_size attribute of the response.
          "value": "S | PETITE | 32"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 15,
      "sku": "sku1237",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12347"
    }
  ]
}
3. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
4. POST Exchange Order - Even Exchange Created
RequestResponse
Copy
Copied
curl --location -g 'https://{{customerurl}}/orders' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "currency": "USD",
    "note": "order note",
    // rma_identifier is taken from the RMA created when the exchange was created
    "rma_identifier": "8b3P5rCjHW",
    // original_order_id is taken from return portal order for which the exchange was created against
    "original_order_id": "ORD1234567",
    "is_gift": false,
    // This scenario is an exchange of a full line of an order. There is one item object in the items array with a quantity of 4 as that what was returned.
    "items": [
        {
            // The sku will be different in the even exchange api as to what was in the RPO or RMA API as the exchange will be for a new item altogether, even if it'\''s the same style/variant.
            "sku": "sku1236",
            // quantity is quantity being exchanged
            "quantity": 4,
            "title": "Blue T-Shirt",
            "unit_price_amount_cents": 12800,
            // product_amount_cents is unit_price_amount_cents * quantity
            "product_amount_cents": 51200,
            "discount_amount_cents": 0,
            "tax_amount_cents": 1024,
            "product_identifier": "32175",
            "variant_identifier": "96027"
        }
    ],
    "customer": {
        // If there is no customer identifier it is recommended to send the shoppers email as the identifier
        "identifier": "219299",
        "first_name": "Ben",
        "last_name": "Wallace",
        "email": "BWallace@gmail.com",
        "phone": "3017607003"
    },
    "shipping_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the shipping_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "billing_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the billing_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "payment": {
        // This is an Optoro generated number for the payment of the exchange order
        "transaction_id": "8ef05fb8-283e-4edd-a3d7-47f9fe520cfe"
    }
}'
Copy
Copied
{
  // order_identifier is the order identifier given by the order capture system
  "order_identifier": "EXCH12345",
  // total_amount_cents is the updated total of the exchange order after re-pricing by the order capture system
  "total_amount_cents": 52224,
  // product_amount_cents is the updated product price of the exchange order after re-pricing by the order capture system
  "product_amount_cents": 51200,
  // tax_amount_cents is the updated tax amount of the exchange order after re-pricing by the order capture system
  "tax_amount_cents": 1024
}
5. POST RMA - RMA Tracking Number Added
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
6. POST RMA - RMA Carrier Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:40:22Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
7. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and exchange so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 52224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full exchange so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
8. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Single-Line, Return of Even Exchange, Mailback

The scenario shown here is for a return of a full even exchange of a single line order where the brand refunds at carrier scan. The full flow is described below followed by sample payloads.

  • Original order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the first return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and they choose a reason code that prompts RX to show exchange options.
  • RX takes the original item's variant identifier and calls the variants API to find the possible items to show the shopper for the exchange. 2. GET Exchange Variants
  • The shopper chooses the exchange item they want and decides to return the original units via the mail back option.
  • When the shopper confirms the return in the portal, a RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. 3. POST RMA
  • At the same time as the initial RMA creation, an Even Exchange message will be posted out from RX. This will tell the forward order system that they need to ship the exchange item to the shopper. The exchange order will have references to the RMA the exchange was created with as well as the order number for the first forward order the exchange was created against. This is in the order_identifier field. 4. POST Exchange Order
  • When the carrier responds with the tracking number and package status, the RMA will be updated and sent out again. This should happen within a few seconds of the initial creation RMA. 5. POST RMA
  • The shopper then drops their package off to the carrier. This moves the package status to "TRANSIT" and triggers a POST RMA to be sent. 6. POST RMA
  • The brand in this scenario refunds at carrier scan so when it receives the POST RMA with the "TRANSIT" package status and "return_method": "mail-back" , it generates the refund. Given this is an even exchange, no money is actually charged against the shopper. This can be seen by the refund_financials object where the shopper_refund_amount_cents is 0.
  • With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 7. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The first RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 8. POST RMA
  • The exchange order is shipped, triggering the exchange order to be pushed to Optoro through the Returns Portal Order API. The "identifier" field is sent as the order identifier of the Exchange Order. 9. POST Returns Portal Order
  • Shopper initiates the return of the exchange order via the Optoro RX portal. They decide to return the full order (4 units of one line) via the mail back option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. The exchange order identifier will be sent in the "exchange order identifier" field and the order identifier for the original forward order will be sent in the "original order identifier" field. 10. POST RMA
  • When the carrier responds with the tracking number and package status, the RMA will be updated and sent out again. This should happen within a few seconds of the initial creation RMA. 11. POST RMA
  • The shopper then drops their exchange order package off to the carrier. This moves the package status to "TRANSIT" and triggers a POST RMA to be sent. 12. POST RMA
  • The brand in this scenario refunds at carrier scan so when it receives the POST RMA with the "TRANSIT" package status and "return_method": "mail-back" , it generates the refund. Given this is a return of an even exchange and no payment was taken directly for the exchange order, the refund needs to go against the original forward order. The original forward order identifier can be seen in the "original order identifier" field on the RMA. The amount to be refunded will be sent in the refund_financials objects of the lines.
  • With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 13. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update for the exchange order with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The second RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 14. POST RMA

Sample payloads for this scenario:

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and exchange so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. GET Exchange Variants - Get Exchange Variants
RequestResponse
Copy
Copied
curl --location -g 'http://{{customerurl}}/sku/96027/variants' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'
Copy
Copied
{
  "variants": [
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "XL"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 10,
      "sku": "sku1236",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12346"
    },
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "S"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 15,
      "sku": "sku1237",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12347"
    }
  ]
}
3. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
4. POST Exchange Order - Even Exchange Created
RequestResponse
Copy
Copied
curl --location -g 'https://{{customerurl}}/orders' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "currency": "USD",
    "note": "order note",
    // rma_identifier is taken from the RMA created when the exchange was created
    "rma_identifier": "8b3P5rCjHW",
    // original_order_id is taken from return portal order for which the exchange was created against
    "original_order_id": "ORD1234567",
    "is_gift": false,
    // This scenario is an exchange of a full line of an order. There is one item object in the items array with a quantity of 4 as that what was returned.
    "items": [
        {
            // The sku will be different in the even exchange api as to what was in the RPO or RMA API as the exchange will be for a new item altogether, even if it'\''s the same style/variant.
            "sku": "sku1236",
            // quantity is quantity being exchanged
            "quantity": 4,
            "title": "Blue T-Shirt",
            "unit_price_amount_cents": 12800,
            // product_amount_cents is unit_price_amount_cents * quantity
            "product_amount_cents": 51200,
            "discount_amount_cents": 0,
            "tax_amount_cents": 1024,
            "product_identifier": "32175",
            "variant_identifier": "96027"
        }
    ],
    "customer": {
        // If there is no customer identifier it is recommended to send the shoppers email as the identifier
        "identifier": "219299",
        "first_name": "Ben",
        "last_name": "Wallace",
        "email": "BWallace@gmail.com",
        "phone": "3017607003"
    },
    "shipping_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the shipping_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "billing_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the billing_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "payment": {
        // This is an Optoro generated number for the payment of the exchange order
        "transaction_id": "8ef05fb8-283e-4edd-a3d7-47f9fe520cfe"
    }
}'
Copy
Copied
{
  // order_identifier is the order identifier given by the order capture system
  "order_identifier": "EXCH12345",
  // total_amount_cents is the updated total of the exchange order after re-pricing by the order capture system
  "total_amount_cents": 52224,
  // product_amount_cents is the updated product price of the exchange order after re-pricing by the order capture system
  "product_amount_cents": 51200,
  // tax_amount_cents is the updated tax amount of the exchange order after re-pricing by the order capture system
  "tax_amount_cents": 1024
}
5. POST RMA - RMA Tracking Number Added
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
6. POST RMA - RMA Carrier Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:40:22Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
7. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and exchange so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 52224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full exchange so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
8. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
9. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems. This is the shipped exchange order so the identifier should be the order_identifier that was responded to Optoro in the Even Exchange API.
            "identifier": "EXCH12345",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-02-22T11:24:21+00:00",
            "updated_at": "2023-02-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipmentment of the exchange order so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipmentment of the exchange order so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999988",
                  // shipped_date can be used to mark the start of the return window. This should be the date the exchange order is shipped.
                  "shipped_date": "2023-02-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
10. POST RMA - RMA for Exchange Order Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value. This will be a different value from the rma_identifier generated for the RMA of the original order.
   "rma_identifier": "9b7L4kPuEV",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-02-27T23:25:09Z",
   "updated_at": "2023-02-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
11. POST RMA - RMA Tracking Number Added
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value. This will be a different value from the rma_identifier generated for the RMA of the original order.
   "rma_identifier": "9b7L4kPuEV",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-02-27T23:25:09Z",
   "updated_at": "2023-02-27T23:25:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202534",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202534",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202534",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202534",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
12. POST RMA - RMA Carrier Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value. This will be a different value from the rma_identifier generated for the RMA of the original order.
   "rma_identifier": "9b7L4kPuEV",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-02-27T23:25:09Z",
   "updated_at": "2023-02-28T13:40:22Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202534",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202534",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202534",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202534",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
13. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems. This is the shipped exchange order so the identifier should be the order_identifier that was responded to Optoro in the Even Exchange API.
            "identifier": "EXCH12345",
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-02-22T11:24:21.01Z",
            "updated_at": "2023-02-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipmentment of the exchange order so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipmentment of the exchange order so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999988",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-02-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000002",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 52224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full exchange so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000002_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-02-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "9b7L4kPuEV"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
14. POST RMA - Exchange Order RMA Refunded
Copy
Copied
curl --location -g 'https://{{customersurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "9b7L4kPuEV",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-02-27T23:25:09Z",
   "updated_at": "2023-02-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202534",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202534",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202534",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202534",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Multi-Line, Partial Return, Partial Exchange, Mailback

The scenario shown here is for a full even exchange of a one line of an order and a full refund of the second line. In this scenario the brand refunds at carrier scan. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and 3 units of another. They choose a reason code for line 1 that prompts RX to show exchange options.
  • RX takes the original line one's variant identifier and calls the variants API to find the possible items to show the shopper for the exchange. 2. GET Exchange Variants
  • The shopper chooses the exchange item they want and decides to return the original units via the mail back option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. 3. POST RMA
  • At the same time as the initial RMA creation, an Even Exchange message will be posted out from RX for the single line they exchanged. This will tell the forward order system that they need to ship the exchange item to the shopper. The exchange order will have references to the RMA the exchange was created with as well as the original order number for the forward order the exchange was created against. This is in the order_identifier field. 4. POST Exchange Order
  • When the carrier responds with the tracking number and package status, the RMA will be updated and sent out again. This should happen within a few seconds of the initial creation RMA. 5. POST RMA
  • The shopper then drops their package off to the carrier. This moves the package status to "TRANSIT" and triggers a POST RMA to be sent. 6. POST RMA
  • The brand in this scenario refunds at carrier scan so when it receives the POST RMA with the "TRANSIT" package status and "return_method": "mail-back" , it generates the refund. Given this is an even exchange of one line and a refund of the other, the refund is not the full order. What should be charged to the shopper is shown in the refund financials object where the shopper refund amount cents is equal to the total of the units refunded but still less than the entire order. Since the shopper exchanged the first line, the optoro_refund_amount_cents will show as the amount for the units exchanged.
  • With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 7. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 8. POST RMA

Sample payloads for this scenario:

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled. Both lines have all units shipped so the status is Shipped
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 85224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 81200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 4024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T17:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment of this line so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment of this line so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 3000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. GET Exchange Variants - Get Exchange Variants
RequestResponse
Copy
Copied
curl --location -g 'http://{{customerurl}}/sku/96027/variants' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'
Copy
Copied
{
  "variants": [
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "XL"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 10,
      "sku": "sku1236",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12346"
    },
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "S"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 15,
      "sku": "sku1237",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12347"
    }
  ]
}
3. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units of one line and a refund of 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
4. POST Exchange Order - Even Exchange Created
RequestResponse
Copy
Copied
curl --location -g 'https://{{customerurl}}/orders' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "currency": "USD",
    "note": "order note",
    // rma_identifier is taken from the RMA created when the exchange was created
    "rma_identifier": "8b3P5rCjHW",
    // original_order_id is taken from return portal order for which the exchange was created against
    "original_order_id": "ORD1234567",
    "is_gift": false,
    // This scenario is an exchange of a full line of an order. There is one item object in the items array with a quantity of 4 as that what was returned.
    "items": [
        {
            // The sku will be different in the even exchange api as to what was in the RPO or RMA API as the exchange will be for a new item altogether, even if it'\''s the same style/variant.
            "sku": "sku1236",
            // quantity is quantity being exchanged
            "quantity": 4,
            "title": "Blue T-Shirt",
            "unit_price_amount_cents": 12800,
            // product_amount_cents is unit_price_amount_cents * quantity
            "product_amount_cents": 51200,
            "discount_amount_cents": 0,
            "tax_amount_cents": 1024,
            "product_identifier": "32175",
            "variant_identifier": "96027"
        }
    ],
    "customer": {
        // If there is no customer identifier it is recommended to send the shoppers email as the identifier
        "identifier": "219299",
        "first_name": "Ben",
        "last_name": "Wallace",
        "email": "BWallace@gmail.com",
        "phone": "3017607003"
    },
    "shipping_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the shipping_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "billing_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the billing_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "payment": {
        // This is an Optoro generated number for the payment of the exchange order
        "transaction_id": "8ef05fb8-283e-4edd-a3d7-47f9fe520cfe"
    }
}'
Copy
Copied
{
  // order_identifier is the order identifier given by the order capture system
  "order_identifier": "EXCH12345",
  // total_amount_cents is the updated total of the exchange order after re-pricing by the order capture system
  "total_amount_cents": 52224,
  // product_amount_cents is the updated product price of the exchange order after re-pricing by the order capture system
  "product_amount_cents": 51200,
  // tax_amount_cents is the updated tax amount of the exchange order after re-pricing by the order capture system
  "tax_amount_cents": 1024
}
5. POST RMA - RMA Tracking Number Added
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units of one line and a refund of 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
6. POST RMA - RMA Carrier Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units of one line and a refund of 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
7. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
             // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 3000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 85224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full refund so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  },
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_2",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 3,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "2"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
8. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units of one line and a refund of 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Single-Line, Full Cancellation, Mailback

The scenario shown here is for a full cancellation of a single line order. The full flow is described below followed by sample payloads.

  • Order is fully canceled, triggering the order to be pushed to Optoro through the Returns Portal Order API with the status as canceled, the quantity_shipped as 0, and the quantity_cancelled as 4. This order will not be able to be returned via the portal due to its canceled status. 1. POST Returns Portal Order

Sample payloads for this scenario:

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Canceled",
            // status can be sent as Created, Shipped, or Canceled. Given all units on the order are cancelled the status is Canceled
             "status": "Canceled",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 0,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 0,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 0,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full cancellation so quantity_shipped is 0
                  "quantity_shipped": 0,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full cancellation so the quantity_canceled is equal to the quantity
                  "quantity_canceled": 4,
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 0,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 0,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'

Single-Line, Partial Cancellation, Refund, Mailback

The scenario shown here is for a partial cancellation of a single line order. The original order was for 4 units but only 1 was shipped and the remaining 3 were canceled. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. The order is in an end state where all units are either canceled or shipped. Given there is 1 unit shipped, the Status is sent as Shipped. The single shipped unit is available to be returned through the RX portal. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the remaining single unit via the mail back option.
  • When the shopper confirms the return in the portal, a RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. 2. POST RMA
  • When the carrier responds with the tracking number and package status, the RMA will be updated and sent out again. This should happen within a few seconds of the initial creation RMA. 3. POST RMA
  • The shopper then drops their package off to the carrier. This moves the package status to "TRANSIT" and triggers a POST RMA to be sent. 4. POST RMA
  • The brand in this scenario refunds at carrier scan so when it receives the POST RMA with the "TRANSIT" package status and "return_method": "mail-back" , it generates the refund. With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 5. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 6. POST RMA

Sample payloads for this scenario:

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled. This scenario is a partial cancellation where the remaining units are shipped so the order is marked as shipped.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 13824,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 12800,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a partial shipment and partial cancellation. Only one unit on the line is shipped and the remaining 3 are cancelled, so quantity_shipped is sent as 1
                  "quantity_shipped": 1,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a partial cancellation where they ship 1 unit and cancel the remaining 3 so the quantity_canceled is 3
                  "quantity_canceled": 3,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 12800,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a partial shipment of only 1 unit there is only 1 object in the items array.
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
3. POST RMA - RMA Tracking Number Added
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a partial shipment of only 1 unit there is only 1 object in the items array.
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
4. POST RMA - RMA Carrier Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:40:22Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a partial shipment of only 1 unit there is only 1 object in the items array.
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
5. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has either been shipped or cancelled in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 13824,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 12800,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a partial shipment and partial cancellation. Only one unit on the line is shipped and the remaining 3 are cancelled, so quantity_shipped is sent as 1
                  "quantity_shipped": 1,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a partial cancellation where they ship 1 unit and cancel the remaining 3 so the quantity_canceled is 3
                  "quantity_canceled": 3,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 12800,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the only 1 of the 4 units are being refunded the total_refund_amount_cents would only be accounting for the price and tax of the single unit.
               "total_refund_amount_cents": 13056,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario has only one unit refunded so there is only one object in the array.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity be the quantity of the unit refunded associated with the RMA. This scenario has only 1 unit refunded as the remaining are cancelled so the quantity is 1.
                  "quantity": 1,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
6. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a partial shipment of only 1 unit there is only 1 object in the items array.
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Single-Line, Cancel RMA, Mailback

The scenario shown here is for a cancellation of a created RMA. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and to return via the mail back option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. 2. POST RMA
  • When the carrier responds with the tracking number and package status, the RMA will be updated and sent out again. This should happen within a few seconds of the initial creation RMA. 3. POST RMA
  • The shopper then calls the call center and requests a cancellation.
  • The call center representative finds the order in Optiturn and cancels the RMA. This triggers a POST RMA call to be made with a status of "CANCELED". The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 4. POST RMA

Sample payloads for this scenario:

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            // created_at should be the tiime the order was created in the Order Management System
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  "upc": "1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": true,
   // giftee_email will only be sent if gift_refund_only is true
   "giftee_email": "email@email.com"
}'
3. POST RMA - RMA Tracking Number Added
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": true,
   // giftee_email will only be sent if gift_refund_only is true
   "giftee_email": "email@email.com"
}'
4. POST RMA - RMA Canceled
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // The status will be sent as CANCELED for RMA'\''s which are canceled.
   "status": "CANCELED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-29T13:40:22Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" and sent as "NOT_RECEIVED" if the RMA is canceled
         "receiving_status": "NOT_RECEIVED",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" and sent as "NOT_RECEIVED" if the RMA is canceled
         "receiving_status": "NOT_RECEIVED",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" and sent as "NOT_RECEIVED" if the RMA is canceled
         "receiving_status": "NOT_RECEIVED",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" and sent as "NOT_RECEIVED" if the RMA is canceled
         "receiving_status": "NOT_RECEIVED",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": true,
   // giftee_email will only be sent if gift_refund_only is true
   "giftee_email": "email@email.com"
}'

Express Returns

Single-Line, Full Refund, Express Returns

The scenario shown here is for a full refund of a single line order via Express Returns where the brand refunds at QR code scan. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line via the Express Returns option.
  • When the shopper confirms the return in the portal, a RMA message will be generated and posted out. This RMA message will not have a tracking number as ER only generates QR codes. The package status will be “PRE-TRANSIT”. 2. POST RMA
  • The shopper then drops their package off to the ER location. This moves the package status to "ACCEPTED" and triggers a POST RMA to be sent. 3. POST RMA
  • The brand in this scenario refunds at QR code scan so when it receives the POST RMA with the "ACCEPTED" package status and "return_method": "express-return" , it generates the refund. With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 4. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 5. POST RMA

The scenario shown here is for a cancellation of a created RMA.

1. POST Returns Portal Orders - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
3. POST RMA - RMA QR Code Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:54:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
4. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 52224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full refund so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
5. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Multi-Line, Full Refund, Express Returns

The scenario shown here is for a full refund of a multi-line order via Express Returns where the brand refunds at QR code scan. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and 3 units of another, via the Express Returns option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number as ER only generates QR codes. The package status will be “PR-ETRANSIT”. 2. POST RMA
  • The shopper then drops their package off to the ER location. This moves the package status to "ACCEPTED" and triggers a POST RMA to be sent. 3. POST RMA
  • The brand in this scenario refunds at QR code scan so when it receives the POST RMA with the "ACCEPTED" package status and "return_method": "express-return" , it generates the refund. With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 4. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 5. POST RMA

The scenario shown here is for a cancellation of a created RMA.

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled. Since this scenario has the order shipped two lines and both lines are now fully shipped the status is sent as Shipped.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 85224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 81200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 4024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T17:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment of this line so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment of this line so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 3000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/124.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units of onle line and 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
3. POST RMA - RMA QR Code Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:54:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units of onle line and 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",

         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
4. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
             // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 3000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/124.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 85224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full refund so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  },
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_2",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 3,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "2"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
5. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units of onle line and 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Single-Line, Even Exchange, Express Returns

The scenario shown here is for an even exchange of a single line order via Express Returns where the brand refunds at QR code scan. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and they choose a reason code that prompts RX to show exchange options.
  • RX takes the original item's variant identifier and calls the variants API to find the possible items to show the shopper for the exchange. 2. GET Exchange Variants
  • The shopper chooses the exchange item they want and decides to return the original units via the Express Returns method.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number as ER only generates QR codes. The package status will be “PRE-TRANSIT”. 3. POST RMA
  • At the same time as the initial RMA creation, an Even Exchange message will be posted out from RX. This will tell the forward order system that they need to ship the exchange item to the shopper. The exchange order will have references to the RMA the exchange was created with as well as the original order number for the forward order the exchange was created against. 4. POST Exchange Order
  • The shopper then drops their package off to the ER location. This moves the package status to "ACCEPTED" and triggers a POST RMA to be sent. 5. POST RMA
  • The brand in this scenario refunds at QR code scan so when it receives the POST RMA with the "ACCEPTED" package status and "return_method": "express-return" , it generates the refund. Given this is an even exchange, no money is actually charged against the shopper. This can be seen by the refund_financials object where the shopper_refund_amount_cents is 0. With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 6. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 7. POST RMA

The scenario shown here is for a cancellation of a created RMA.

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and exchange so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. GET Exchange Variants - Get Exchange Variants
RequestResponse
Copy
Copied
curl --location -g 'http://{{customerurl}}/sku/96027/variants' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'
Copy
Copied
{
  "variants": [
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "XL"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 10,
      "sku": "sku1236",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12346"
    },
    {
      "attributes": [
        // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "S"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 15,
      "sku": "sku1237",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12347"
    }
  ]
}
3. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
4. POST Exchange Order - Even Exchange Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/orders' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "currency": "USD",
    "note": "order note",
    // rma_identifier is taken from the RMA created when the exchange was created
    "rma_identifier": "8b3P5rCjHW",
    // original_order_id is taken from return portal order for which the exchange was created against
    "original_order_id": "ORD1234567",
    "is_gift": false,
    // This scenario is an exchange of a full line of an order. There is one item object in the items array with a quantity of 4 as that what was returned.
    "items": [
        {
            // The sku will be different in the even exchange api as to what was in the RPO or RMA API as the exchange will be for a new item altogether, even if it'\''s the same style/variant.
            "sku": "sku1236",
            // quantity is quantity being exchanged
            "quantity": 4,
            "title": "Blue T-Shirt",
            "unit_price_amount_cents": 12800,
            // product_amount_cents is unit_price_amount_cents * quantity
            "product_amount_cents": 51200,
            "discount_amount_cents": 0,
            "tax_amount_cents": 1024,
            "product_identifier": "32175",
            "variant_identifier": "96027"
        }
    ],
    "customer": {
        // If there is no customer identifier it is recommended to send the shoppers email as the identifier
        "identifier": "219299",
        "first_name": "Ben",
        "last_name": "Wallace",
        "email": "BWallace@gmail.com",
        "phone": "3017607003"
    },
    "shipping_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the shipping_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "billing_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the billing_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "payment": {
        // This is an Optoro generated number for the payment of the exchange order
        "transaction_id": "8ef05fb8-283e-4edd-a3d7-47f9fe520cfe"
    }
}'
5. POST RMA - RMA QR Code Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:54:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
6. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 52224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full exchange so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
7. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customersurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Single-Line, Even Exchange with all_size, Express Returns

The scenario shown here is for an even exchange of a single line order via Express Returns where the brand refunds at QR code scan. This is with an order that has an item with multiple size differentiators. This means that in the variants response, an attribute called all_size is sent that describes all the size attributes. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and they choose a reason code that prompts RX to show exchange options.
  • RX takes the original item's variant identifier and calls the variants API to find the possible items to show the shopper for the exchange. In the response to the variants API, one of the attributes will be all_size . This describes all of the item's sizes in a single field. 2. GET Exchange Variants
  • The shopper chooses the exchange item they want and decides to return the original units via the Express Returns method.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number as ER only generates QR codes. The package status will be “PRE-TRANSIT”. 3. POST RMA
  • At the same time as the initial RMA creation, an Even Exchange message will be posted out from RX. This will tell the forward order system that they need to ship the exchange item to the shopper. The exchange order will have references to the RMA the exchange was created with as well as the original order number for the forward order the exchange was created against. 4. POST Exchange Order
  • The shopper then drops their package off to the ER location. This moves the package status to "ACCEPTED" and triggers a POST RMA to be sent. 5. POST RMA
  • The brand in this scenario refunds at QR code scan so when it receives the POST RMA with the "ACCEPTED" package status and "return_method": "express-return" , it generates the refund. Given this is an even exchange, no money is actually charged against the shopper. This can be seen by the refund_financials object where the shopper_refund_amount_cents is 0. With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 6. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 7. POST RMA

The scenario shown here is for a cancellation of a created RMA.

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and exchange so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. GET Exchange Variants - Get Exchange Variants
RequestResponse
Copy
Copied
curl --location -g 'http://{{customersurl}}/sku/96027/variants' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'
Copy
Copied
{
  "variants": [
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "XL"
        },
        {
          "name": "Variant",
          "value": "PETITE"
        },
        {
          "name": "Length",
          "value": "32"
        },
        {
          "name": "all_size",
          // The value for the all_size attribute should be the different size values with '|' as a delimiter. In this instanze the item can be described by size, variant, and length so they are all included in the all_size attribute of the response.
          "value": "XL | PETITE | 32"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 10,
      "sku": "sku1236",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12346"
    },
    {
      "attributes": [
        // attributes array clarifies the type of variant the sku is, the name specifies what type of variant the attribute describes. The all_size attribute is needed if there are more than one size differentiations, such as Variant or Length.
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "S"
        },
        {
          "name": "Variant",
          "value": "PETITE"
        },
        {
          "name": "Length",
          "value": "32"
        },
        {
          "name": "all_size",
          // The value for the all_size attribute should be the different size values with '|' as a delimiter. In this instanze the item can be described by size, variant, and length so they are all included in the all_size attribute of the response.
          "value": "S | PETITE | 32"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 15,
      "sku": "sku1237",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12347"
    }
  ]
}
3. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
4. POST Exchange Order - Even Exchange Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/orders' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "currency": "USD",
    "note": "order note",
    // rma_identifier is taken from the RMA created when the exchange was created
    "rma_identifier": "8b3P5rCjHW",
    // original_order_id is taken from return portal order for which the exchange was created against
    "original_order_id": "ORD1234567",
    "is_gift": false,
    // This scenario is an exchange of a full line of an order. There is one item object in the items array with a quantity of 4 as that what was returned.
    "items": [
        {
            // The sku will be different in the even exchange api as to what was in the RPO or RMA API as the exchange will be for a new item altogether, even if it'\''s the same style/variant.
            "sku": "sku1236",
            // quantity is quantity being exchanged
            "quantity": 4,
            "title": "Blue T-Shirt",
            "unit_price_amount_cents": 12800,
            // product_amount_cents is unit_price_amount_cents * quantity
            "product_amount_cents": 51200,
            "discount_amount_cents": 0,
            "tax_amount_cents": 1024,
            "product_identifier": "32175",
            "variant_identifier": "96027"
        }
    ],
    "customer": {
        // If there is no customer identifier it is recommended to send the shoppers email as the identifier
        "identifier": "219299",
        "first_name": "Ben",
        "last_name": "Wallace",
        "email": "BWallace@gmail.com",
        "phone": "3017607003"
    },
    "shipping_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the shipping_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "billing_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the billing_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "payment": {
        // This is an Optoro generated number for the payment of the exchange order
        "transaction_id": "8ef05fb8-283e-4edd-a3d7-47f9fe520cfe"
    }
}'
5. POST RMA - RMA QR Code Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:54:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
6. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 52224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full exchange so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
7. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Single-Line, Return of Even Exchange, Express Returns

The scenario shown here is for a return of a full even exchange of a single line order via Express Returns where the brand refunds at QR code scan. The full flow is described below followed by sample payloads.

  • Original order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and they choose a reason code that prompts RX to show exchange options.
  • RX takes the original item's variant identifier and calls the variants API to find the possible items to show the shopper for the exchange. 2. GET Exchange Variants
  • The shopper chooses the exchange item they want and decides to return the original units via the Express Returns method.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number as ER only generates QR codes. The package status will be "PRE-TRANSIT". 3. POST RMA
  • At the same time as the initial RMA creation, an Even Exchange message will be posted out from RX. This will tell the forward order system that they need to ship the exchange item to the shopper. The exchange order will have references to the RMA the exchange was created with as well as the order number for the first forward order the exchange was created against. This is in the order_identifier field. 4. POST Exchange Order
  • The shopper then drops their package off to the ER location. This moves the package status to "ACCEPTED" and triggers a POST RMA to be sent. 5. POST RMA
  • The brand in this scenario refunds at QR code scan so when it receives the POST RMA with the "ACCEPTED" package status and "return_method": "express-return" , it generates the refund. Given this is an even exchange, no money is actually charged against the shopper. This can be seen by the refund_financials object where the shopper_refund_amount_cents is 0. With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 6. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA for the original order is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 7. POST RMA
  • The exchange order is shipped, triggering the exchange order to be pushed to Optoro through the Returns Portal Order API. The "identifier" field is sent as the order identifier of the Exchange Order. 8. POST Returns Portal Order
  • Shopper initiates the return of the exchange order via the Optoro RX portal. They decide to return the full order which is 4 units of one line via the Express Returns method.
  • When the shopper confirms the return in the portal, a RMA message will be generated and posted out. This RMA message will not have a tracking number as ER only generates QR codes. The package status will be "PRE-TRANSIT". The exchange order identifier will be sent in the exchange_order_identifier field and the order identifier for the original forward order will be sent in the original_order_identifier field. 9. POST RMA
  • The shopper then drops their exchange order package off to the carrier. This moves the package status to "TRANSIT" and triggers a POST RMA to be sent. 10. POST RMA
  • The brand in this scenario refunds at carrier scan so when it receives the POST RMA with the "TRANSIT" package status and "return_method": "mail-back" , it generates the refund. Given this is a return of an even exchange and no payment was taken directly for the exchange order, the refund needs to go against the original forward order. The original forward order identifier can be seen in the original_order_identifier field on the RMA. The amount to be refunded will be sent in the refund_financials objects of the lines.
  • With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 11. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update for the exchange order with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The second RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 12. POST RMA

The scenario shown here is for a cancellation of a created RMA.

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and exchange so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. GET Exchange Variants - Get Exchange Variants
RequestResponse
Copy
Copied
curl --location -g 'http://{{customerurl}}/sku/96027/variants' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'
Copy
Copied
{
  "variants": [
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "XL"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 10,
      "sku": "sku1236",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12346"
    },
    {
      "attributes": [
        // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "S"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 15,
      "sku": "sku1237",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12347"
    }
  ]
}
3. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
4. POST Exchange Order - Even Exchange Created
RequestResponse
Copy
Copied
curl --location -g 'https://{{customerurl}}/orders' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "currency": "USD",
    "note": "order note",
    // rma_identifier is taken from the RMA created when the exchange was created
    "rma_identifier": "8b3P5rCjHW",
    // original_order_id is taken from return portal order for which the exchange was created against
    "original_order_id": "ORD1234567",
    "is_gift": false,
    // This scenario is an exchange of a full line of an order. There is one item object in the items array with a quantity of 4 as that what was returned.
    "items": [
        {
            // The sku will be different in the even exchange api as to what was in the RPO or RMA API as the exchange will be for a new item altogether, even if it'\''s the same style/variant.
            "sku": "sku1236",
            // quantity is quantity being exchanged
            "quantity": 4,
            "title": "Blue T-Shirt",
            "unit_price_amount_cents": 12800,
            // product_amount_cents is unit_price_amount_cents * quantity
            "product_amount_cents": 51200,
            "discount_amount_cents": 0,
            "tax_amount_cents": 1024,
            "product_identifier": "32175",
            "variant_identifier": "96027"
        }
    ],
    "customer": {
        // If there is no customer identifier it is recommended to send the shoppers email as the identifier
        "identifier": "219299",
        "first_name": "Ben",
        "last_name": "Wallace",
        "email": "BWallace@gmail.com",
        "phone": "3017607003"
    },
    "shipping_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the shipping_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "billing_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the billing_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "payment": {
        // This is an Optoro generated number for the payment of the exchange order
        "transaction_id": "8ef05fb8-283e-4edd-a3d7-47f9fe520cfe"
    }
}'
Copy
Copied
{
  // order_identifier is the order identifier given by the order capture system
  "order_identifier": "EXCH12345",
  // total_amount_cents is the updated total of the exchange order after re-pricing by the order capture system
  "total_amount_cents": 52224,
  // product_amount_cents is the updated product price of the exchange order after re-pricing by the order capture system
  "product_amount_cents": 51200,
  // tax_amount_cents is the updated tax amount of the exchange order after re-pricing by the order capture system
  "tax_amount_cents": 1024
}
5. POST RMA - RMA QR Code Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:54:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
6. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and exchange so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 52224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full exchange so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
7. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
8. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems. This is the shipped exchange order so the identifier should be the order_identifier that was responded to Optoro in the Even Exchange API.
            "identifier": "EXCH12345",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-02-22T11:24:21+00:00",
            "updated_at": "2023-02-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipmentment of the exchange order so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipmentment of the exchange order so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999988",
                  // shipped_date can be used to mark the start of the return window. This should be the date the exchange order is shipped.
                  "shipped_date": "2023-02-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
9. POST RMA - RMA for Exchange Order Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value. This will be a different value from the rma_identifier generated for the RMA of the original order.
   "rma_identifier": "9b7L4kPuEV",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-02-27T23:25:09Z",
   "updated_at": "2023-02-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
10. POST RMA - RMA QR Code Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value. This will be a different value from the rma_identifier generated for the RMA of the original order.
   "rma_identifier": "9b7L4kPuEV",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-02-27T23:25:09Z",
   "updated_at": "2023-02-28T13:40:22Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
11. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems. This is the shipped exchange order so the identifier should be the order_identifier that was responded to Optoro in the Even Exchange API.
            "identifier": "EXCH12345",
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-02-22T11:24:21.01Z",
            "updated_at": "2023-02-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipmentment of the exchange order so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipmentment of the exchange order so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999988",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-02-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000002",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 52224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full exchange so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000002_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-02-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "9b7L4kPuEV"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
12. POST RMA - Exchange Order RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "9b7L4kPuEV",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-02-27T23:25:09Z",
   "updated_at": "2023-02-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements. For the RMA of the exchange order the identifier of the exchange order is sent,
         "order_identifier": "EXCH12345",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. This RMA is for a straight return of an exchange order so the exchange_order_identifier is null
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against. This should be referenced to determine which order to generate the refund against for returns of exchanges,
         "original_order_identifier": "ORD1234567",
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this scenario, since this RMA is a straight return this is sent as false
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and optoro_refund_amount_cents is sent at 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a return of an order the refund will go to the shopper and shopper_refund_amount_cents is sent as the same amount as estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of a refund of an even exchange will have refund_type set to "REFUND"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'

Multi-Line, Partial Return, Partial Exchange, Mailback

The scenario shown here is for a full even exchange of a one line of an order and a full refund of the second line. In this scenario, the brand refunds at QR code scan. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order, which is 4 units of one line and 3 units of another. They choose a reason code for line 1 that prompts RX to show exchange options.
  • RX takes the original line one's variant identifier and calls the variants API to find the possible items to show the shopper for the exchange. 2. GET Exchange Variants
  • The shopper chooses the exchange item they want and decides to return the original units via the express returns option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number or package status associated with it. 3. POST RMA
  • At the same time as the initial RMA creation, an Even Exchange message will be posted out from RX for the single line they exchanged. This will tell the forward order system that they need to ship the exchange item to the shopper. The exchange order will have references to the RMA the exchange was created with as well as the original order number for the forward order the exchange was created against. 4. POST Exchange Order
  • The shopper then drops their package off to the express returns drop-off location. This moves the package status to "ACCEPTED" and triggers a POST RMA to be sent. 5. POST RMA
  • The brand in this scenario refunds at QR code scan so when it receives the POST RMA with the "ACCEPTED" package status and "return_method": "express-returns" , it generates the refund. Given this is an even exchange of one line and a refund of the other, the refund is not for the full order. What should be charged to the shopper is shown in the refund_financials object where the shopper_refund_amount_cents is equal to the total of the units refunded but still less than the entire order. Since the shopper exchanged the first line, the optoro_refund_amount_cents will show as the amount for the units exchanged.
  • With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 6. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 7. POST RMA

The scenario shown here is for a cancellation of a created RMA.

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled. Both lines have all units shipped so the status is Shipped
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 85224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 81200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 4024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T17:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment of this line so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment of this line so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 3000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. GET Exchange Variants - Get Exchange Variants
RequestResponse
Copy
Copied
curl --location -g 'http://{{customerurl}}/sku/96027/variants' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json'
Copy
Copied
{
  "variants": [
    {
      // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
      "attributes": [
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "XL"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 10,
      "sku": "sku1236",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12346"
    },
    {
      "attributes": [
        // attributes array clarifies the type of variant the sku is, the name specifies if the value is for color or size
        {
          "name": "Color",
          "value": "Blue"
        },
        {
          "name": "Size",
          "value": "S"
        }
      ],
      // quantity_in_stock is the available units of the variant
      "quantity_in_stock": 15,
      "sku": "sku1237",
      // title will be displayed to the shopper in the UI
      "title": "Blue T-Shirt",
      // unit_price_amount_cents is used to determine whether the variant is shown. If the unit_price_amount_cents is more than the original unit then the variant is not shown.
      "unit_price_amount_cents": 12800,
      // image_url and product_url will be used to display the variant and provide a link to the product detail page of the variant
      "image_url": "https://media.media.com/media/123.jpg",
      "product_url": "https://media.media.com/sku12347"
    }
  ]
}
3. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units of one line and a refund of 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Upon initial RMA creation the package_tracking_status and package_tracking_status will be null for all return methods
         "tracking_number": null,
         "package_tracking_status": null,
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
4. POST Exchange Order - Even Exchange Created
RequestResponse
Copy
Copied
curl --location -g 'https://{{customerurl}}/orders' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "currency": "USD",
    "note": "order note",
    // rma_identifier is taken from the RMA created when the exchange was created
    "rma_identifier": "8b3P5rCjHW",
    // original_order_id is taken from return portal order for which the exchange was created against
    "original_order_id": "ORD1234567",
    "is_gift": false,
    // This scenario is an exchange of a full line of an order. There is one item object in the items array with a quantity of 4 as that what was returned.
    "items": [
        {
            // The sku will be different in the even exchange api as to what was in the RPO or RMA API as the exchange will be for a new item altogether, even if it'\''s the same style/variant.
            "sku": "sku1236",
            // quantity is quantity being exchanged
            "quantity": 4,
            "title": "Blue T-Shirt",
            "unit_price_amount_cents": 12800,
            // product_amount_cents is unit_price_amount_cents * quantity
            "product_amount_cents": 51200,
            "discount_amount_cents": 0,
            "tax_amount_cents": 1024,
            "product_identifier": "32175",
            "variant_identifier": "96027"
        }
    ],
    "customer": {
        // If there is no customer identifier it is recommended to send the shoppers email as the identifier
        "identifier": "219299",
        "first_name": "Ben",
        "last_name": "Wallace",
        "email": "BWallace@gmail.com",
        "phone": "3017607003"
    },
    "shipping_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the shipping_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "billing_address": {
        "name": "Ben Wallace",
        "street1": "1001 G St NW",
        "city": "Washington",
        // Note: In the Return Portal order the billing_address uses State but in the Even Exchanges API it uses province
        "province": "DC",
        "zip_code": "20001",
        "country_code": "US",
        "phone": "3017607003"
    },
    "payment": {
        // This is an Optoro generated number for the payment of the exchange order
        "transaction_id": "8ef05fb8-283e-4edd-a3d7-47f9fe520cfe"
    }
}'
Copy
Copied
{
  // order_identifier is the order identifier given by the order capture system
  "order_identifier": "EXCH12345",
  // total_amount_cents is the updated total of the exchange order after re-pricing by the order capture system
  "total_amount_cents": 52224,
  // product_amount_cents is the updated product price of the exchange order after re-pricing by the order capture system
  "product_amount_cents": 51200,
  // tax_amount_cents is the updated tax amount of the exchange order after re-pricing by the order capture system
  "tax_amount_cents": 1024
}
5. POST RMA - RMA QR Code Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units of one line and a refund of 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
6. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is an even exchange of 4 units of one line and a refund of 3 units of another there are 7 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange. Since this scenario is for an even exchange created for a full line exchange_order_identifier is populated
         "exchange_order_identifier": "EXCH12345",
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order. For this even exchange scenario is_exchange is sent as true
         "is_exchange": true,
         "sku": "sku1234",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this is a full even exchange optoro_refund_amount_cents should be equal to the estimated_refund_amount_cents
            "optoro_refund_amount_cents": 13056,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this is a full even exchange shopper_refund_amount_cents should be equal to 0
            "shopper_refund_amount_cents": 0
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE". This scenario of an even exchange will have refund_type set to "EVEN_EXCHANGE"
         "refund_type": "EVEN_EXCHANGE"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "2",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1235",
         // Once the RMA has been created and the carrier has provided the tracking number and label the package_tracking_status will be updated to PRE_TRANSIT and the tracking_number willbe populated. This change in package_tracking_status will trigger the POST RMA message.
         "tracking_number": "92023909899840543401202533",
         // When the package is picked up by the carrier the package_tracking_status is updated to TRANSIT and a POST RMA message is generated
         "package_tracking_status": "TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 11000,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage. Since this unit is a refund the optoro_refund_amount_cents for the unit is 0.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage. Since this unit is a refund the shopper_refund_amount_cents for the unit is equal to estimated_refund_amount_cents.
            "shopper_refund_amount_cents": 11000
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE", This unit is being returned so the refund_type should be sent as REFUND
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "mail-back",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
7. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
             // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been shipped in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 3000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the order is fully refunded the total_refund_amount_cents should equal the header level total_amount_cents
               "total_refund_amount_cents": 85224,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario is a full refund so all units are included.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 4,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  },
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_2",
                  // quantity should match the quantity field in the items array when the units are all returned like in this example
                  "quantity": 3,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "2"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'

Single-Line, Full Cancellation, Express Returns

The scenario shown here is for a full cancellation of a single line order. The full flow is described below followed by sample payloads.

Order is fully canceled, triggering the order to be pushed to Optoro through the Returns Portal Order API with the status as canceled and the quantity_shipped as 0. This order will not be able to be returned via the portal due to its canceled status. 1. POST Returns Portal Order

The scenario shown here is for a cancellation of a created RMA.

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Canceled",
            // status can be sent as Created, Shipped, or Canceled. Given all units on the order are canceled the status is Canceled
             "status": "Canceled",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 0,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 0,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 0,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full cancellation so quantity_shipped is 0
                  "quantity_shipped": 0,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full cancellation so the quantity_canceled is the same as the quantity.
                  "quantity_canceled": 4,
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 0,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 0,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'

Single-Line, Partial Cancellation, Refund, Express Returns

The scenario shown here is for a partial cancellation of a single line order. The original order was for 4 units but only 1 was shipped and the remaining 3 were canceled. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. The order is in an end state where all units are either canceled or shipped. Given there is 1 unit shipped, the Status is sent as Shipped and the single shipped unit is available to be returned through the RX portal. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the remaining single unit via the Express Returns option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number as ER only generates QR codes. The package status will be “PRE-TRANSIT”. 2. POST RMA
  • The shopper then drops their package off to the ER location. This moves the package status to "ACCEPTED" and triggers a POST RMA to be sent. 3. POST RMA
  • The brand in this scenario refunds at QR code scan so when it receives the POST RMA with the "ACCEPTED" package status and "return_method": "express-return" , it generates the refund. With the refund generated, it sends back to Optoro a Returns Portal Order message with the refund details. 4. POST Returns Portal Order
  • Upon receiving the Returns Portal Order update with the refund details, the RMA is moved to Refunded. This again triggers a POST RMA sent outbound from Optoro. The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 5. POST RMA

The scenario shown here is for a cancellation of a created RMA.

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled. This scenario is a partial cancellation where the remaining units are shipped so the order is marked as shipped.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 13824,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 12800,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a partial shipment and partial cancellation. Only one unit on the line is shipped and the remaining 3 are cancelled, so the quantity_shipped is sent as 1.
                  "quantity_shipped": 1,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a shipment of 1 unit and cancellation of 3 units so the quantity_canceled is 3
                  "quantity_canceled": 3,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 12800,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a partial shipment of only 1 unit there is only 1 object in the items array.
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'
3. POST RMA - RMA QR Code Scan
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T13:54:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a partial shipment of only 1 unit there is only 1 object in the items array.
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
4. POST Returns Portal Order - Returns Portal Order Refunded
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // raw_status is the status of the order in external systems, typically OMS status
            "raw_status": "Refunded",
            // Status shoould be sent as Shipped since the full order has been either shipped or cancelled in this scenario
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 13824,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 12800,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21.01Z",
            "updated_at": "2023-01-28T19:42:49.23Z",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a partial shipment and partial cancellation. Only one unit on the line is shipped and the remaining 3 are canceled, this is indicated by the status being sent as Shipped, meaning the order has all it'\''s units as either shipped or canceled. Optoro reads the status of shipped and assumes the units not shipped are canceled, in this case since the quantity is 4 and the quantity_shipped is 1 then 3 units are canceled.
                  "quantity_shipped": 1,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a shipment of 1 unit and cancellation of 3 units so the quantity_canceled is 3
                  "quantity_canceled": 3,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 12800,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            "refunds": [
               {
               // The identifier in the header of the refund object needs to be unique across all refunds
               "identifier": "RET202301280000001",
               //  In this scenario where the only 1 of the 4 units are being refunded the total_refund_amount_cents would only be accounting for the price and tax of the single unit.
               "total_refund_amount_cents": 13056,
               // refund_line_items array should only include the skus and units that are associated with this refund. This scenario has only one unit refunded so there is only one object in the array.
               "refund_line_items": [
                  {
                  // The identifier in the refund_line_items object needs to be unique across all refunds
                  "identifier": "RET202301280000001_1",
                  // quantity be the quantity of the unit refunded associated with the RMA. This scenario has only 1 unit refunded as the remaining are cancelled so the quantity is 1.
                  "quantity": 1,
                  // order_item_identifier should match the identifier field of the sku in the items array
                  "order_item_identifier": "1"
                  }
               ],
               // The note is not required and only used for data purposes
               "note": "Returned",
               // created_at needs to be sent with a date in the future.
               "created_at": "2023-01-28T19:42:49.23Z",
               // rma_identifier is not required but recommended to be sent to assist with identifying the RMA when there are multiple RMAs for a single order.
               "rma_identifier": "8b3P5rCjHW"
               }
            ],
            "discounts": []
         }
      ]
   }
}'
5. POST RMA - RMA Refunded
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "REFUNDED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-28T19:42:59.23Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a partial shipment of only 1 unit there is only 1 object in the items array.
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. Since this is the status to refund for ER if not refunding at the warehouse the RMA will show ACCEPTED when the RMA is Refunded.
         "package_tracking_status": "ACCEPTED",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false
}'

Single-Line, Cancel RMA, Express Returns

The scenario shown here is for a cancellation of a created RMA. The full flow is described below followed by sample payloads.

  • Order is shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. 1. POST Returns Portal Order
  • Shopper initiates the return via the Optoro RX portal. They decide to return the full order (4 units of one line) via the Express Returns option.
  • When the shopper confirms the return in the portal, an RMA message will be generated and posted out. This RMA message will not have a tracking number as ER only generates QR codes. The package status will be “PRE-TRANSIT”. 2. POST RMA
  • The shopper then calls the call center and requests a cancellation.
  • The call center representative finds the order in Optiturn and cancels the RMA. This triggers a POST RMA call to be made with a status of "CANCELED". The RMA is now closed in Optoro and when the external system ingests the POST RMA, the RMA should get closed there as well. 3. POST RMA

The scenario shown here is for a cancellation of a created RMA.

1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 52224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 51200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 1024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg",
                  // weight is needed for determining ER eligibility if catalog is not provided
                  "weight": 1.12
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            // discounts object needs to be sent but only as an empty array like below
            "discounts": []
         }
      ]
   }
}'
2. POST RMA - RMA Created
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // Status should only be looked at if you are using managed services RM
   "status": "CREATED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-27T23:25:09Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         // For Express Returns RMA'\''s the RMA will be created with tracking_number as null and package_tracking_status in PRE_TRANSIT status
         "tracking_number": null,
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'
3. POST RMA - RMA Canceled
Copy
Copied
curl --location -g 'https://{{customerurl}}/rmas' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
   // rma_identifier is an Optoro generate value
   "rma_identifier": "8b3P5rCjHW",
   // The status will be sent as CANCELED for RMA'\''s which are canceled.
   "status": "CANCELED",
   "created_at": "2023-01-27T23:25:09Z",
   "updated_at": "2023-01-29T13:54:12Z",
   // Only items associated with the RMA will be sent in the items array. If multiple units of the same order_line_item_identifier are returned then there will be multiple items object for the order_line_item_identifier, one for each unit returned. Since this scenario is a refund of 4 units there are 4 objects in the items array
   "items": [
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      },
      {
         // order_line_item_identifier identifier is equal to the item level identifier from the Return Portal Order
         "order_line_item_identifier": "1",
         // order_identifier can be sent os either the order level identifier or secondary_identifier depending on external systems requirements
         "order_identifier": "ORD1234567",
         // exchange_order_identifier is the identifier of the exchange order when the item being returned is for a new exchange.
         "exchange_order_identifier": null,
         // For RMAs created for exchange orders original_order_identifier refers to the order identifier of the order that the exchage was initially created against
         "original_order_identifier": null,
         "return_reason": "Changed Mind",
         // is_exchange indicates whether the RMA item belongs to an exchange order
         "is_exchange": false,
         "sku": "sku1234",
         "tracking_number": null,
         // When the shopper either drops off the item or has the item picked up the QR code will be scanned which will move the RMA'\''s package_tracking_status to ACCEPTED. This change will trigger an outbound POST RMA to be sent.
         "package_tracking_status": "PRE_TRANSIT",
         // receiving_status can be "PENDING", "RECEIVED", or "NOT_RECEIVED" but only  populated if it is RM managed services
         "receiving_status": "PENDING",
         // The refund_financials object should be used for determing how much to refund only for even exchanges.
         "refund_financials": {
            // estimated_refund_amount_cents is the total possible refund amount of the unit based on goods returned.
            "estimated_refund_amount_cents": 13056,
            // optoro_refund_amount_cents is the amount Optoro will be paid based on instant exchange usage.
            "optoro_refund_amount_cents": 0,
            // shopper_refund_amount_cents is the estimated amount the shopper will be refunded based on instant exchange usage.
            "shopper_refund_amount_cents": 13056
         },
         // refund_type can be sent as "REFUND", "EVEN_EXCHANGE", or "UNEVEN_EXCHANGE"
         "refund_type": "REFUND"
      }
   ],
   // return_method can be "mail-back", "express-returns", or "customer-keep"
   "return_method": "express-returns",
   "return_shipping_cost_cents": 0,
   // gift_refund_only will be sent as true for gift orders to allow financial systems to determine if they need to refund to a gift card and not the original payment method
   "gift_refund_only": false,
   // warehouse_id denotes the warehouse the return will be routed to if there are multiple return warehouses used
   "warehouse_id": "21"
}'

Tags

FinalSale OrderLine

The scenario shown here is for a full shipment of a multi-line order where one line is marked as unable to be returned due to FinalSale. This scenario is enabled with the Returns Portal Order.

  • Order is fully shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. The order has 2 lines. The first line item contains a tag to show that it is unable to be returned due to FinalSale. The second item is not tagged because it is available to be returned. In the portal, the shopper would see line one grayed out and unavailable for return. The second line displays and is available to be returned. 1. POST Returns Portal Order
1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 83224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 81200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 2024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            // The tag string array is populated with FinalSale for line 1 but not populated for line 2 so line 1 will not be available to be returned while line 2 will be
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": ["FinalSale"],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg"
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/124.jpg"
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            "discounts": []
         }
      ]
   }
}'

BOPIS OrderLine

The scenario shown here is for a full shipment of a multi-line order where one line is marked as a BOPIS order using the pickup_in_store tag. Often, retailers will have trouble reconciling online returns of items picked up in the store and thus will try to restrict those orders from being returned online. This tag allows them to stop the order from being returned. This scenario is enabled with the Returns Portal Order.

  • Order is fully shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. The order has 2 lines. The first line contains a tag to show that it is unable to be returned due to pickup_in_store . The second line is not tagged because it is available to be returned. In the portal, the shopper would see line one grayed out and unavailable for return. The second line displays and is available to be returned. 1. POST Returns Portal Order
1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 83224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 81200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 2024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            // The tag string array is populated with pickup_in_store for line 1 but not populated for line 2 so line 1 will not be available to be returned while line 2 will be
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 4,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 4,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": null,
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Black T-Shirt",
                  "tags": ["pickup_in_store"],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 12800,
                  "image_url": "https://media.media.com/media/123.jpg"
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/124.jpg"
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            "discounts": []
         }
      ]
   }
}'

Gift Card OrderLine

The scenario shown here is for a full shipment of a multi-line order where one line is marked as a gift card order using the gift-card tag. Often, retailers will want to restrict gift cards from being returned. This tag allows gift card lines to be identified and stopped from being returned. This scenario is enabled with the Returns Portal Order.

  • Order is fully shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. The order has 2 lines. The first line contains a tag to show that it is unable to be returned because it is a gift-card . The second line is not tagged because it is available to be returned. In the portal, the shopper would see line one grayed out and unavailable for return. The second line displays and is available to be returned. 1. POST Returns Portal Order
1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 83224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 81200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 2024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            // The tag string array is populated with gift-card for line 1 but not populated for line 2 so line 1 will not be available to be returned while line 2 will be
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 1,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 1,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Gift Card",
                  "tags": ["gift-card"],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 51200,
                  "image_url": "https://media.media.com/media/123.jpg"
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/124.jpg"
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            "discounts": []
         }
      ]
   }
}'

Third Party OrderLine

The scenario shown here is for a full shipment of a multi-line order where one line is marked as an order-line originating from a third party using the Thirdparty tag. Often, retailers will want to restrict lines from third-party sites to be returned online without calling the shopper service team first. This tag allows third-party order-lines to be identified and stopped from being returned. This scenario is enabled with the Returns Portal Order.

  • Order is fully shipped, triggering the order to be pushed to Optoro through the Returns Portal Order API. The order has 2 lines. The first line contains a tag to show that it is unable to be returned due to being Thirdparty . The second line is not tagged because it is available to be returned. In the portal, the shopper would see line one grayed out and unavailable for return. The second line displays and is available to be returned. 1. POST Returns Portal Order
1. POST Returns Portal Order - Create Returns Portal Order
Copy
Copied
curl --location -g 'https://orders.{{url}}/returns_portal_orders' \
--header 'Content-Type: application/json' \
--header 'Authorization: bearer {{access_token}}' \
--header 'Api-Version: 3' \
--data-raw '{
   "returns_portal_order": {
      "orders": [
         {
            // identifier is the order identifier used by the customers internal ecomm systems
            "identifier": "ORD1234567",
            // secondary_identifier is only needed if the order originated from a 3rd party system and that 3rd party order identifier needs to be tracked
            "secondary_identifier": "RO-1234567",
            "raw_status": "fulfilled",
            // status can be sent as Created, Shipped, or Canceled.
             "status": "Shipped",
            // total_amount_cents is the sum of the header level total_amount_cents and product_amount_cents
            "total_amount_cents": 83224,
            // product_amount_cents at the header level is the sum of the product_amount_cents for each line
            "product_amount_cents": 81200,
            // tax_amount_cents at the header level is the sum of the tax_amount_cents for each line
            "tax_amount_cents": 2024,
            "discount_amount_cents": 0,
            "shipping_amount_cents": 0,
            "shipping_tax_amount_cents": 0,
            "currency": "USD",
            "tags": [],
            "created_at": "2023-01-22T11:24:21+00:00",
            "updated_at": "2023-01-23T13:37:19+00:00",
            // The tag string array is populated with Thirdparty for line 1 but not populated for line 2 so line 1 will not be available to be returned while line 2 will be
            "items": [
               {
                  // identifier is the forward order lines identifier
                  "identifier": "1",
                  "sku": "sku1234",
                  // The quantity is the total quantity on the order-line
                  "quantity": 1,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 1,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32174",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96027",
                  "title": "Blue T-Shirt",
                  // By sending Thirdparty this line is not allowed to be returned in the portal
                  "tags": ["Thirdparty"],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 51200,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1024,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 51200,
                  "image_url": "https://media.media.com/media/123.jpg"
               },
               {
                  // identifier is the forward order lines identifier
                  "identifier": "2",
                  "sku": "sku1235",
                  // The quantity is the total quantity on the order-line
                  "quantity": 3,
                  // The quantity_shipped is the total quantity of shipped units on the order-line.  This scenario is a full shipment and refund so the quantity_shipped is equal to the quantity
                  "quantity_shipped": 3,
                  // The quantity_canceled is the total quantity of canceled units on the order-line.  This scenario is a full shipment and refund so the quantity_canceled is 0
                  "quantity_canceled": 0,
                  "tracking_number": "1Z9999999999999999",
                  // shipped_date can be used to mark the start of the return window
                  "shipped_date": "2023-01-23T13:37:19+00:00",
                  // product_identifier is the customers unique Id to that product (ex. same SKU from different vendors). Send SKU if no product_identifier exists
                  "product_identifier": "32175",
                  // variant_identifier is used to find the skus that should be made available to the shopper as part of the even exchange
                  "variant_identifier": "96028",
                  "title": "White T-Shirt",
                  "tags": [],
                  // product_amount_cents is the unit_price_amount_cents multiplied by the quantity_shipped
                  "product_amount_cents": 30000,
                  // tax_amount_cents is the tax, in cents, for all units for the sku in the shipment
                  "tax_amount_cents": 1000,
                  "discount_amount_cents": 0,
                  // unit_price_amount_cents is the price, in cents, for a single unit of the sku
                  "unit_price_amount_cents": 10000,
                  "image_url": "https://media.media.com/media/124.jpg"
               }
            ],
            "customer": {
               // If there is no customer identifier it is recommended to send the shoppers email as the identifier
               "identifier": "219299",
               "first_name": "Ben",
               "last_name": "Wallace",
               "email": "BWallace@gmail.com",
               "phone": "3017607003"
            },
            "shipping_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            "billing_address": {
               "name": "Ben Wallace",
               "street1": "1001 G St NW",
               "city": "Washington",
               "state": "DC",
               "zip_code": "20001",
               "country_code": "US",
               "phone": "3017607003"
            },
            // The transactions object needs to be sent but only as an empty array like below
            "transactions": [],
            // For the initial creation of the return portal order the refund object should be sent but as an empty array like below
            "refunds": [],
            "discounts": []
         }
      ]
   }
}'
© 2010 – 2024 Optoro, Inc. For official use only by authorized users. Use subject to terms of license agreement.