OXXO Pay

To better understand and test cash payments with OXXO Pay, you can use the following sample data. This allows you to simulate a real checkout, generate a payment reference, and confirm that the order is marked as paid when the customer pays at an OXXO store.

❗️

IMPORTANT

OXXO Pay is available for MXN orders in Mexico. The customer email is required. The maximum amount per payment is $11,000.00 MXN. The payment reference expires in 5 days.

Setting up an order for OXXO Pay

  1. Setup: Ensure you have access to the Ecart Pay API environment, use the Sandbox base URL (https://sandbox.ecartpay.com) and a valid authorization token.
  2. Create a Test Order: Create an order in sandbox with currency set to MXN and an email. Optionally restrict checkout to cash so only OXXO Pay is shown.
    1. email is required. Without it, OXXO Pay cannot generate a reference.
    2. currency must be MXN.
    3. totals (sum of items) must be $11,000.00 MXN or less.
    4. available_payment_methods can be set to ["cash"] to hide cards and bank transfers during this test.

Endpoint

POST https://sandbox.ecartpay.com/api/orders

Headers

  • Authorization: <your_jwt_token>
  • Content-Type: application/json

Request example

curl --location 'https://sandbox.ecartpay.com/api/orders' \
--header 'Authorization: <your_jwt_token>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "email": "[email protected]",
  "first_name": "Maria",
  "last_name": "Lopez",
  "phone": "5512345678",
  "currency": "MXN",
  "available_payment_methods": ["cash"],
  "items": [
    {
      "name": "OXXO Pay test order",
      "quantity": 1,
      "price": 350.00
    }
  ],
  "notify_url": "https://merchant.example.com/webhooks/ecartpay",
  "redirect_url": "https://merchant.example.com/orders/return"
}'

Response example

{
  "id": "68daa3b554802cf804a3374f",
  "number": "OR01667152",
  "status": "created",
  "email": "[email protected]",
  "first_name": "Maria",
  "last_name": "Lopez",
  "currency": "MXN",
  "totals": {
    "subtotal": 350,
    "total": 350,
    "tax": 0,
    "discount": 0,
    "shipping": 0
  },
  "pay_link": "https://sandbox.ecartpay.com/checkout?id=68daa3b554802cf804a3374f"
}
  1. Open checkout: Send the customer (or yourself, in sandbox) to pay_link. Select OXXO Pay and confirm the payment. Ecart Pay generates a cash reference and barcode. The order moves to pending.
    1. Payment at the store is cash only. The barcode does not need to be printed; it can be shown on a phone.
    2. The same reference is emailed to the customer email.
    3. Pay before the expiration date shown on the voucher (5 days from creation).
  1. Verify the voucher: After confirming OXXO Pay, retrieve the order and check the payment reference.
curl --location 'https://sandbox.ecartpay.com/api/orders/68daa3b554802cf804a3374f' \
--header 'Authorization: <your_jwt_token>'

The payments array includes the cash method details. Example:

{
  "id": "68daa3b554802cf804a3374f",
  "status": "pending",
  "currency": "MXN",
  "payments": [
    {
      "id": "ord_2tV2HyVSTfdrsXqqV",
      "status": "pending",
      "type": "cash",
      "currency": "MXN",
      "amount": 35000,
      "gateway": "oxxopay",
      "method": {
        "expires_at": "2026-08-31T18:00:00.000Z",
        "reference": "98000014505724",
        "barcode_url": "https://barcodes.digitalfemsa.io/sandbox_reference.png",
        "merchants": [
          {
            "key": "oxxo",
            "name": "OXXO"
          }
        ],
        "steps": [
          "Go to the nearest OXXO store to make the payment.",
          "Mention that you will make a cash payment through OXXO Pay.",
          "Show the cashier the barcode or reference number that was sent to your email and verify the information.",
          "Make your payment in cash. The store will give you a receipt as proof of your payment; keep it for any clarification."
        ]
      }
    }
  ]
}
  • status on the order should be pending until the customer pays at OXXO.
  • payments[0].method.reference is the number the cashier captures.
  • payments[0].method.barcode_url is the barcode image. Display it in your UI; do not require a printout.
  • payments[0].amount is in cents (350.00 MXN35000). totals.total remains in pesos.

You can also read the public order (no token) while the voucher is shown to the customer:

GET https://sandbox.ecartpay.com/api/orders/public/68daa3b554802cf804a3374f

  1. Error Handling: Test for potential errors, such as missing email or amounts over the limit. This helps ensure the robustness of the integration.
ConditionExpected result
Order without email400 — The email is required to create a payment with Oxxo Pay.
Amount greater than $11,000.00 MXN400 — OXXO payments cannot exceed $11,000.
Unverified merchant, amount over $500.00 MXN409 — cash limit exceeded
Currency other than MXN422 — currency not available in this payment method
  1. End-to-End Testing: Complete the testing cycle by verifying that, once the cash payment is confirmed, the order is marked as paid in Ecart Pay. Do not fulfill on pending. Fulfill only after paid.

In production, OXXO typically reports the payment within about 10 minutes. The customer also receives a confirmation email from OXXO Pay.



Testing webhooks functionality

You can set up a webhook for orders.update and orders.confirmation to be notified when the OXXO payment is completed. Unlike bank transfer sandbox tests, you must create and process an order first so there is a pending OXXO reference to settle.

Subscribe from the dashboard or via API:

{
  "url": "https://merchant.example.com/webhooks/ecartpay",
  "events": [
    "orders.create",
    "orders.update",
    "orders.confirmation"
  ]
}

You can also set notify_url on the order. Ecart Pay will POST status changes to that URL.

Events

EventWhen
orders.createThe order is created (status: created).
orders.updateThe order status changes (pending, paid, cancelled, refunded).
orders.confirmationThe cash payment is confirmed (status: paid).

Cancelled includes expired references (the customer did not pay within 5 days).

Webhook payload

When the customer pays at OXXO:

{
  "event": "orders.update",
  "data": {
    "id": "68daa3b554802cf804a3374f",
    "status": "paid"
  }
}
{
  "event": "orders.confirmation",
  "data": {
    "id": "68daa3b554802cf804a3374f",
    "status": "paid"
  }
}

Use GET /api/orders/:id after the webhook to load the full order, including paid_at and payment details.

Return HTTP 200 from your endpoint. See Webhooks in Ecart Pay and Webhook Authentication for HMAC headers (x-pay-timestamp, x-pay-webhook-id, x-pay-signature).



By leveraging this testing data and the sandbox checkout, developers can ensure the smooth integration of OXXO Pay into their workflows, providing customers with a reliable cash payment method at any OXXO store.


Did this page help you?