Accept OXXO payments
DocsBetaLast updated: August 18th 2024, @ 11:09:25 am
OXXO is a Mexican chain of convenience stores with +19,800 stores in Latin America. It represents nearly 20% of online transactions in Mexico and allows customers to pay bills and online purchases in-store with cash. OXXO payments have a low risk of fraud or unrecognized payments because the customer must provide the payment in person.
Countries | Payment type | Payment flow | Currencies | Maximum amount | Refunds |
---|---|---|---|---|---|
Mexico (MX ) | voucher | redirect | MXN | 10,000 | N/A |
How it works
Checkout flow
- Buyer chooses to pay with OXXO.
- Buyer provides their first name, last name, and email.
- The payment voucher is presented to the buyer.
- Buyer completes the payment at OXXO.
- Merchant receives the successful payment completion webhook notification and PayPal moves the funds to the merchant account.
- Merchant ships the goods.
Eligibility
- Available to merchants in Mexico only.
- Billing agreements, multiple seller payments, and shipping callback aren't supported.
- Only supports order capture. Doesn't support order authorization. See Payments webhooks.
- Chargebacks aren't supported.
- JS SDK
- Orders API
Buyer experience
Know before you code
Note: The integration steps for implementing alternative payment methods are similar. If you've integrated another alternative payment method before, you can likely reuse that code with adjustments for this payment method.
- Complete the steps in Get started to get your sandbox account information from the Developer Dashboard:
- Client ID: Authenticates your account with PayPal and identifies an app in your sandbox.
- Client Secret: Authorizes an app in your sandbox. Keep this secret safe and don't share it.
- Business account credentials
- Make sure the preference for receiving payments in your PayPal business account is set to accept and convert them to the default currency. To verify, in your profile select Account Settings > Payment preferences > Block payments and select Update to mark this preference.
- This client-side and server-side integration uses the following:
- Make sure you're subscribed to the following webhook events:
- Listen for the
CHECKOUT.ORDER.APPROVED
webhook in order to retrieve order details. - Listen for the
PAYMENT.CAPTURE.PENDING
,PAYMENT.CAPTURE.COMPLETED
, andPAYMENT.CAPTURE.DENIED
webhooks, which indicate payment capture status.
- Listen for the
- By adding funding sources to your checkout integration, you agree to the PayPal alternative payment methods agreement. This is in addition to the user agreement applicable to the country in which your business is physically located.
- Request approval to enable this payment method by visiting these Sandbox and Live links. Replace
MERCHANT-COUNTRY
in the URL with the 2-character country code for the merchant's country of operation. ReplacePRODUCT
andCAPABILITY
with the corresponding payment method:- Sandbox:
https://www.sandbox.paypal.com/bizsignup/entry?product=PRODUCT&capabilities=CAPABILITY&country.x=MERCHANT-COUNTRY
- Live:
https://www.paypal.com/bizsignup/entry?product=PRODUCT&capabilities=CAPABILITY&country.x=MERCHANT-COUNTRY
- Sandbox:
Use Postman to explore and test PayPal APIs.
1. Add PayPal JavaScript SDK
Add or update the JavaScript SDK script on your web page.
1<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&components=buttons,payment-fields,marks,funding-eligibility&enable-funding=oxxo¤cy=MXN"></script>
This table lists the parameters you pass to the JavaScript SDK.
Query param | Default | Description |
client-id
|
none | Your PayPal REST client ID. This identifies your PayPal account and determines where transactions are paid. |
components
|
buttons
|
A comma-separated list of components to enable. The buttons , payment-fields , marks , and funding-eligibility components are required for payment fields components.
|
enable-funding
|
none | The enabled payment methods to show in buttons and marks.
Note: By default, PayPal JavaScript SDK provides smart logic to display only appropriate marks and buttons for the current buyer. This optional parameter bypasses the buyer country check for desired payment methods. For example: |
currency
|
USD
|
This is the currency for the payment. This value needs to match the currency used when creating the order. |
locale
|
automatic | The locale renders components. By default PayPal detects the correct locale for the buyer based on their geolocation and browser preferences. It is recommended to pass this parameter with a supported locale if you need the PayPal buttons to render in the same language as the rest of your site. |
intent
|
capture
|
The intent for the transaction. This determines whether the funds are captured immediately while the buyer is present on the page. |
commit
|
true
|
This indicates that the final amount won't change after the buyer returns to your site from PayPal. |
vault
|
false
|
Whether the payment information in the transaction will be saved. Save your customers' payment information for billing agreements, subscriptions, or recurring payments. Marking this parameter false shows all funding sources, including payment methods that can't be saved.
|
See additional, optional parameters.
2. Render payment mark
You can use a mark integration for payment fields components to present the payment method options to the buyer as radio buttons.
1paypal.Marks({2 fundingSource: paypal.FUNDING.OXXO3}).render('#oxxo-mark')
3. Render payment fields
Payment fields offer easy integration to collect payment information from buyers. Fields dynamically render based on the selected funding source and you can customize the fields to align with your brand.
The OXXO payment fields collect first name, last name, and email.
If there are validation errors in the input fields, they'll show on the click of the button.
1paypal.PaymentFields({2 fundingSource: paypal.FUNDING.OXXO,3 /* style object (optional) */4 style: {5 /* customize field attributes (optional) */6 variables: {},7 /* set custom rules to apply to fields classes (optional) */8 rules: {},9 },10 fields: {11 /* fields prefill info (optional) */12 name: {13 value: "John Doe",14 },15 email: {16 value: "jdoe@example.com",17 },18 }19})20.render("#oxxo-container")
Note: A multipage checkout integration is also available. This might be applicable for German merchants to comply with the 2012 Button Solution or others with a multipage checkout experience.
For style
parameters, please reference this style page: Custom style for payment fields
4. Render payment button
paypal.Buttons({
fundingSource: paypal.FUNDING.OXXO,
style: {
label: "pay",
},
createOrder() {
return fetch("/my-server/create-paypal-order", {
method: "post",
// use the "body" param to optionally pass additional order information
// like product skus and quantities
body: JSON.stringify({
cart: [
{
sku: "YOUR_PRODUCT_STOCK_KEEPING_UNIT",
quantity: "YOUR_PRODUCT_QUANTITY",
},
],
}),
})
.then((response) => response.json())
.then((order) => order.id);
},
onApprove(data) {
return fetch("/my-server/capture-paypal-order", {
method: "post",
body: JSON.stringify({
orderID: data.orderID
})
})
.then((response) => response.json())
.then((orderData) => {
// Successful capture! For dev/demo purposes:
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
const transaction = orderData.purchase_units[0].payments.captures[0];
console.log('Transaction Status:', transaction.status);
console.log('Transaction ID:', transaction.id);
// When ready to go live, remove the alert and show a success message within this page. For example:
// const element = document.getElementById('paypal-button-container');
// element.innerHTML = '<h3>Thank you for your payment!</h3>';
// Or go to another URL: window.location.href = 'thank_you.html';
});
},
onCancel(data, actions) {
/* Incomplete checkout. Buyer closed the window before order confirmation. */
/* Show a message to restart the checkout process. */
console.log(`Order Canceled - ID: ${data.orderID}`);
},
onError(err) {
console.error(err);
}
}).render("#oxxo-btn");
Use paypal.Buttons().isEligible()
to check if the funding source is eligible.
1var mark = paypal.Marks({2 fundingSource: paypal.FUNDING.OXXO3})4var fields = paypal.PaymentFields({5 fundingSource: paypal.FUNDING.OXXO,6})7var button = paypal.Buttons({8 fundingSource: paypal.FUNDING.OXXO9})10if(button.isEligible()) {11 mark.render('#oxxo-mark');12 fields.render("#oxxo-container");13 button.render("#oxxo-btn");14}
createOrder
Implement the createOrder
function to allow the JavaScript SDK to submit buyer information and set up the transaction on the click of the button.
Note: OXXO requires orders to be created in a currency of MXN.
Use your server-side Create order call to set up the details of a one-time transaction including the amount, line item detail, and more.
If order creation fails, the Orders API can return an error in the console.
After order creation, orders are confirmed with buyer-selected payment source. If the order cannot be processed with the selected payment source, the relevant errors are returned in the console.
onCancel
Implement the optional onCancel()
function to show a cancellation page or return to the shopping cart.
onError
Implement the optional onError()
function to handle errors and display generic error message or page to the buyers. This error handler is a catch-all. Errors at this point aren't expected to be handled beyond showing a generic error message or page.
5. Handle webhook events
A webhook handler is a script you create on your server that completes specific actions on webhooks that hit your listener URL.
CHECKOUT.ORDER.APPROVED
- Listen for this webhook to retrieve order details, including theBARCODE_URL
for the voucher. Use this URL to send the voucher in emails or to display it again. Order capture is performed automatically. No additional code required.PAYMENT.CAPTURE.PENDING
- The funds for this payment were not yet credited to the payee's PayPal account. The buyer has not yet completed the transaction.PAYMENT.CAPTURE.COMPLETED
- The funds for this payment were credited to the payee's PayPal account. The buyer completed the transaction and goods can be delivered.PAYMENT.CAPTURE.DENIED
- The funds could not be captured. The buyer did not complete the transaction before the voucher's expiration.
See Subscribe to checkout webhooks for more information.
Here are some additional resources as you create webhook handler code:
- Webhook Management API - Manage webhooks, list event notifications, and more.
- Webhook events
- Checkout webhook events - Checkout buyer approval-related webhooks.
- Order webhook events - Other order-related webhooks.
- Show order details endpoint - Determine the status of an order.
Sample integration
See a sample OXXO integration in the PayPal GitHub repository.