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.

POST

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"