Skip to main content
OXXO is a cash-based payment method in Mexico that provides buyers with a voucher and reference number for in-store payment.

Setup

Follow the Stripe setup instructions before configuring OXXO.

Capabilities

Supported countries

Supported currencies

Configuration

For shared APM credentials, see Stripe APM credentials.

Approval URL (optional)

By default, the connector returns an approval URL that redirects buyers to a Stripe-hosted page with instructions for completing an OXXO cash payment. If required, you can set a different approval URL here which allows you to build your own page for showing the OXXO voucher to buyers. When set, the Approval URL is returned with a Session Token appended as a query parameter named token. This Session Token can be used with the Transaction Session API to retrieve the details required to build your own page.

Webhooks

OXXO payments are completed asynchronously, so you must configure webhooks to update the status of transactions. Webhooks are configured in the Stripe Dashboard within Developer Settings under Webhooks. The OXXO connector relies on the following Stripe webhook event:
  • payment_intent.succeeded

Integration

The default integration for OXXO via Stripe uses a redirect to payments page hosted by Stripe.

Redirect integration

Start by creating a new transaction with the following required fields.
var transaction = await client.Transactions.CreateAsync(
  transactionCreate: new TransactionCreate()
  {
    Amount = 1299,
    Currency = "MXN",
    Country = "MX",
    PaymentMethod =
      TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
        new RedirectPaymentMethodCreate()
        {
          Method = "oxxo",
          Country = "MX",
          Currency = "MXN",
          RedirectUrl = "https://example.com/callback",
        }
      ),
  }
);
amount := int64(1299)
currency := "MXN"
country := "MX"
method := components.RedirectPaymentMethodCreateMethodOxxo
redirectUrl := "https://example.com/callback"

redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
  Method: method,
  Country: country,
  Currency: currency,
  RedirectURL: redirectUrl,
}
paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

transactionCreate := components.TransactionCreate{
  Amount:        amount,
  Currency:      currency,
  Country:       &country,
  PaymentMethod: &paymentMethod,
}

transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
  .transactionCreate(TransactionCreate.builder()
    .amount(1299L)
    .currency("MXN")
    .country("MX")
    .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
      .method(RedirectPaymentMethodCreateMethod.OXXO)
      .country("MX")
      .currency("MXN")
      .redirectUrl("https://example.com/callback")
      .build()))
    .build())
  .call();

Transaction transaction = transactionResponse.transaction().orElse(null);
$transactionCreate = new TransactionCreate(
  amount: 1299,
  currency: 'MXN',
  country: 'MX',
  paymentMethod: new RedirectPaymentMethodCreate(
    method: 'oxxo',
    country: 'MX',
    currency: 'MXN',
    redirectUrl: 'https://example.com/callback'
  )
);
$response = self::$sdk->transactions->create($transactionCreate);
$transaction = $response->transaction;
transaction: models.Transaction = client.transactions.create(
  amount=1299,
  currency="MXN",
  country="MX",
  payment_method={
    "method": "oxxo",
    "country": "MX",
    "currency": "MXN",
    "redirect_url": "https://example.com/callback",
  }
)
const transaction = await gr4vy.transactions.create({
  amount: 1299,
  currency: "MXN",
  country: "MX",
  paymentMethod: {
    method: "oxxo",
    country: "MX",
    currency: "MXN",
    redirectUrl: "https://example.com/callback"
  }
})
After the transaction is created, the API response includes a payment_method.approval_url and a processing status.
{
  "type": "transaction",
  "id": "ea1efdd0-20f9-44d9-9b0b-0a3d71e9b625",
  "payment_method": {
    "type": "payment-method",
    "approval_url": "https://payments.stripe.com/oxxo/voucher/test..."
  },
  "method": "oxxo"
}
Redirect the buyer to the approval_url where they see an OXXO voucher and instructions to complete the cash payment. Once the buyer completes the cash payment at an OXXO location, the transaction progresses to a capture_succeeded state in response to a webhook from Stripe.

Direct integration

If you intend to use your own hosted page for presenting the buyer with the OXXO voucher, you can include an integration_client parameter set to web, ios or android when creating a new transaction.
var transaction = await client.Transactions.CreateAsync(
  transactionCreate: new TransactionCreate()
  {
    Amount = 1299,
    Currency = "MXN",
    Country = "MX",
    IntegrationClient = "ios",
    PaymentMethod =
      TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
        new RedirectPaymentMethodCreate()
        {
          Method = "oxxo",
          Country = "MX",
          Currency = "MXN",
          RedirectUrl = "myapp://callback",
        }
      ),
  }
);
amount := int64(1299)
currency := "MXN"
country := "MX"
integrationClient := "ios"
method := components.RedirectPaymentMethodCreateMethodOxxo
redirectUrl := "myapp://callback"

redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
  Method: method,
  Country: country,
  Currency: currency,
  RedirectURL: redirectUrl,
}
paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

transactionCreate := components.TransactionCreate{
  Amount:            amount,
  Currency:          currency,
  Country:           &country,
  IntegrationClient: &integrationClient,
  PaymentMethod:     &paymentMethod,
}

transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
  .transactionCreate(TransactionCreate.builder()
    .amount(1299L)
    .currency("MXN")
    .country("MX")
    .integrationClient("ios")
    .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
      .method(RedirectPaymentMethodCreateMethod.OXXO)
      .country("MX")
      .currency("MXN")
      .redirectUrl("myapp://callback")
      .build()))
    .build())
  .call();

Transaction transaction = transactionResponse.transaction().orElse(null);
$transactionCreate = new TransactionCreate(
  amount: 1299,
  currency: 'MXN',
  country: 'MX',
  integrationClient: 'ios',
  paymentMethod: new RedirectPaymentMethodCreate(
    method: 'oxxo',
    country: 'MX',
    currency: 'MXN',
    redirectUrl: 'myapp://callback'
  )
);
$response = self::$sdk->transactions->create($transactionCreate);
$transaction = $response->transaction;
transaction: models.Transaction = client.transactions.create(
  amount=1299,
  currency="MXN",
  country="MX",
  integration_client="ios",
  payment_method={
    "method": "oxxo",
    "country": "MX",
    "currency": "MXN",
    "redirect_url": "myapp://callback",
  }
)
const transaction = await gr4vy.transactions.create({
  amount: 1299,
  currency: "MXN",
  country: "MX",
  integrationClient: "ios",
  paymentMethod: {
    method: "oxxo",
    country: "MX",
    currency: "MXN",
    redirectUrl: "myapp://callback"
  }
})
After the transaction is created, the API response includes a session_token which can be used to get the session data for the transaction, which can be used to build a custom page for displaying the OXXO voucher.
POST /transactions/:transaction_id/session?token=:session_token

{
    "session_data": {
        "paymentIntentId": "pi_3StlgnRAbJldLcy50NYwrdAN",
        "oxxoDisplayDetails": {
            "expires_after": 1770098399,
            "hosted_voucher_url": "https://payments.stripe.com/oxxo/voucher/test...",
            "number": "12345678901234657890123456789012"
        }
    },
    "default_completion_url": "https://example.com/callback",
    "integration_client": "ios"
}