Skip to main content

Payments India

With WhatsApp Payments in India, users can review an order and pay for it without leaving WhatsApp, using UPI apps, net banking, wallets or cards.

How it works​

  1. The order is created. The user selects products from your WhatsApp catalogue and sends you their cart, or you create an order for products the user has shown interest in.
  2. You send the order details. You send an order_details message with the items, amounts and payment options. The user reviews the order and pays.
  3. You update the order status. When you receive the payment, and as the order progresses, you send order_status messages to keep the user informed.

Before you begin​

Accept the WhatsApp Payments terms​

Before you create a payment configuration, accept the WhatsApp Payments Terms of Service. Until you do, sending payment messages fails with error code 131005, the error response contains the link to accept the terms.

Create a payment configuration​

Your WhatsApp Business Account (WABA) must be linked to a payment configuration. Each configuration has a unique name. In the order_details message you specify which configuration to use for a checkout.

You can create a configuration in two ways.

Option 1: WhatsApp Manager (recommended)

  1. In WhatsApp Manager, go to Account tools → Payment configurations and select India.
  2. Click Add new configuration.
  3. Enter a configuration name, select a payment provider and complete the gateway authorisation.

Option 2: Onboarding API

Create the configuration with a request to Meta's Graph API. Two types are supported:

TypeUse for
Payment gatewayProviders such as Razorpay, PayU or Zaakpay.
UPI VPAA direct UPI handle (virtual payment address).
Payment gateway
curl -X POST 'https://graph.facebook.com/v21.0/{WABA_ID}/payment_configuration' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"configuration_name": "my-payment-config",
"purpose_code": "00",
"merchant_category_code": "0000",
"provider_name": "razorpay",
"redirect_url": "https://your-redirect-url.com"
}'
UPI VPA
curl -X POST 'https://graph.facebook.com/v21.0/{WABA_ID}/payment_configuration' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"configuration_name": "my-upi-config",
"purpose_code": "00",
"merchant_category_code": "0000",
"provider_name": "upi_vpa",
"merchant_vpa": "merchantname@bank"
}'
FieldRequiredDescription
configuration_nameYesUnique name of the configuration. Used in order_details messages to select the configuration.
provider_nameYesupi_vpa, razorpay, payu or zaakpay.
merchant_category_codeNoMerchant category code (MCC) of your business.
purpose_codeNoPurpose code of the transaction type.
merchant_vpaConditionalRequired for upi_vpa: your UPI handle.
redirect_urlNoWhere you are redirected after completing the gateway authorisation.

For a payment gateway, the response contains an OAuth URL. Open it and complete the authorisation to connect the configuration to your gateway account.

Response
{
"oauth_url": "https://www.facebook.com/payment/onboarding/init/",
"expiration": 1721687287,
"success": true
}

The link expires at the expiration timestamp. If it expires, request a new one with Meta's Regenerate OAuth Link endpoint.

The Onboarding API also lets you list, retrieve and delete payment configurations. See Meta's Payments India onboarding APIs.

Configuration status​

StatusMeaning
Needs_ConnectingThe OAuth authorisation with the payment gateway is pending.
Needs_TestingConnected, but not yet verified with a test transaction.
ActiveReady to process payments.

When the configuration status changes, you receive an update on your webhook.


Send the order details​

The order_details message shows the order summary and a button to pay. You can send it as an interactive message within the customer service window, or as a template outside it.

Requirements​

  • currency must be INR.
  • total_amount must equal subtotal + tax + shipping − discount.
  • action.name must be review_and_pay.
  • order.status must be pending.
  • reference_id must be unique per order.
Unique reference IDs

Use a unique reference_id for every order, to avoid duplicates and to track payment status accurately. If you send several order_details messages for the same order or invoice, add a sequence number to the reference_id.

Supported payment methods​

payment_settings[].typeDescription
upi_intent_linkUPI intent link. Supported integrations: Dynamic VPA, Cashfree, BillDesk and CCAvenue.
payment_linkA payment link (including enhanced payment links).
payment_gatewayA payment gateway linked through your payment configuration.

Amounts​

All amounts are objects with a value and an offset. The actual amount is value ÷ offset. The offset must be 100.

Amount example
{ "value": 21000, "offset": 100 }

This represents ₹210.00.

Interactive order_details message​

Fields​

FieldRequiredDescription
interactive.typeYesorder_details
headerNoImage header.
body.textYesMessage text.
footer.textNoFooter text.
action.nameYesreview_and_pay
parameters.reference_idYesYour unique order reference.
parameters.typeYesdigital-goods or physical-goods.
parameters.beneficiariesConditionalRequired for physical-goods: the recipients of the shipment. Not shown to the user, but required for legal and compliance reasons.
parameters.currencyYesINR
parameters.total_amountYesTotal amount.
parameters.payment_settingsYesPayment method. See Supported payment methods.
parameters.order.statusYespending
parameters.order.typeNoquick_pay: hides the Review and pay button and shows only Pay now.
parameters.order.catalog_idNoYour catalogue ID. See Catalogue and non-catalogue items.
parameters.order.expirationNotimestamp (UNIX time) and description. After this time, the pay button is disabled.
parameters.order.items[]YesThe items: name, amount, quantity, and optionally sale_amount (discounted price per item) and retailer_id.
parameters.order.subtotalYesSum of the item amounts.
parameters.order.taxNoTax amount, with optional description.
parameters.order.shippingNoShipping costs, with optional description.
parameters.order.discountNoDiscount, with optional description and discount_program_name.

Catalogue and non-catalogue items​

Items from…Required item fields
Your catalogueSet order.catalog_id, and retailer_id (the content ID in your catalogue) on each item.
Outside a catalogueOmit catalog_id and retailer_id. Add country_of_origin, importer_name and importer_address to each item.

Examples​

Physical goods
{
"messages": {
"authentication": {
"productToken": "YOUR_PRODUCT_TOKEN"
},
"msg": [
{
"from": "00916098765432",
"to": [
{ "number": "00916012345678" }
],
"body": {
"type": "auto",
"content": "Here is your order summary."
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"interactive": {
"type": "order_details",
"header": {
"type": "image",
"image": {
"link": "https://your-media-url.com/image.jpg"
}
},
"body": {
"text": "Here is your order summary. Please review and complete your payment."
},
"footer": {
"text": "Thank you for shopping with us!"
},
"action": {
"name": "review_and_pay",
"parameters": {
"reference_id": "order-ref-12345",
"type": "physical-goods",
"beneficiaries": [
{
"name": "Jane Doe",
"address_line1": "B8/733 Nand Nagri",
"address_line2": "Near Police Station",
"city": "East Delhi",
"state": "Delhi",
"country": "India",
"postal_code": "110093"
}
],
"currency": "INR",
"total_amount": { "value": 21000, "offset": 100 },
"payment_settings": [
{
"type": "upi_intent_link",
"upi_intent_link": {
"link": "upi://pay?pa=merchant_vpa&pn=Merchant_Name&mc=1234&purpose=00&tr=pg_generated_id"
}
}
],
"order": {
"status": "pending",
"type": "quick_pay",
"expiration": {
"timestamp": "1798761600",
"description": "Order will be cancelled after expiry."
},
"items": [
{
"name": "Cotton T-Shirt",
"amount": { "value": 10000, "offset": 100 },
"sale_amount": { "value": 8000, "offset": 100 },
"quantity": 2,
"country_of_origin": "India",
"importer_name": "Acme Imports Pvt Ltd",
"importer_address": {
"address_line1": "B8/733 Nand Nagri",
"address_line2": "Near Police Station",
"city": "East Delhi",
"zone_code": "DL",
"postal_code": "110093",
"country_code": "IN"
}
}
],
"subtotal": { "value": 16000, "offset": 100 },
"tax": { "value": 2000, "offset": 100, "description": "GST" },
"shipping": { "value": 5000, "offset": 100, "description": "Standard delivery" },
"discount": {
"value": 2000,
"offset": 100,
"description": "Promo discount",
"discount_program_name": "WELCOME10"
}
}
}
}
}
}
]
}
}
]
}
}
Digital goods
{
"messages": {
"authentication": {
"productToken": "YOUR_PRODUCT_TOKEN"
},
"msg": [
{
"from": "00916098765432",
"to": [
{ "number": "00916012345678" }
],
"body": {
"type": "auto",
"content": "Here is your order summary."
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"interactive": {
"type": "order_details",
"body": {
"text": "Here is your order summary. Please review and complete your payment."
},
"action": {
"name": "review_and_pay",
"parameters": {
"reference_id": "order-ref-12346",
"type": "digital-goods",
"currency": "INR",
"total_amount": { "value": 19060, "offset": 100 },
"payment_settings": [
{
"type": "upi_intent_link",
"upi_intent_link": {
"link": "upi://pay?pa=merchant_vpa&pn=Merchant_Name&mc=1234&purpose=00&tr=pg_generated_id"
}
}
],
"order": {
"status": "pending",
"items": [
{
"name": "Premium Subscription - 1 Month",
"amount": { "value": 19900, "offset": 100 },
"sale_amount": { "value": 17000, "offset": 100 },
"quantity": 1,
"country_of_origin": "India",
"importer_name": "Acme Digital Pvt Ltd",
"importer_address": {
"address_line1": "12 Tech Park",
"address_line2": "Whitefield",
"city": "Bengaluru",
"zone_code": "KA",
"postal_code": "560066",
"country_code": "IN"
}
}
],
"subtotal": { "value": 17000, "offset": 100 },
"tax": { "value": 3060, "offset": 100, "description": "GST 18%" },
"discount": {
"value": 1000,
"offset": 100,
"description": "Launch offer",
"discount_program_name": "LAUNCH20"
}
}
}
}
}
}
]
}
}
]
}
}
Catalogue items
{
"messages": {
"authentication": {
"productToken": "YOUR_PRODUCT_TOKEN"
},
"msg": [
{
"from": "00916098765432",
"to": [
{ "number": "00916012345678" }
],
"body": {
"type": "auto",
"content": "Here is your order summary."
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"interactive": {
"type": "order_details",
"body": {
"text": "Here is your order summary."
},
"action": {
"name": "review_and_pay",
"parameters": {
"reference_id": "order-ref-12347",
"type": "digital-goods",
"currency": "INR",
"total_amount": { "value": 3700, "offset": 100 },
"payment_settings": [
{
"type": "upi_intent_link",
"upi_intent_link": {
"link": "upi://pay?pa=merchant_vpa&pn=Merchant%20Name&mc=mc_code&purpose=purpose_code&tr=transaction_record"
}
}
],
"order": {
"status": "pending",
"catalog_id": "333817456789654321",
"items": [
{
"retailer_id": "4270312345abc",
"name": "License Key",
"amount": { "value": 2700, "offset": 100 },
"quantity": 1
}
],
"subtotal": { "value": 2700, "offset": 100 },
"shipping": { "value": 1000, "offset": 100, "description": "Delivery fee" }
}
}
}
}
}
]
}
}
]
}
}

Example of an order_details message

Payment method variants​

The examples above use a UPI intent link. For other payment methods, replace payment_settings with one of the following:

UPI intent link
"payment_settings": [
{
"type": "upi_intent_link",
"upi_intent_link": {
"link": "upi://pay?pa=merchant_vpa&pn=Merchant%20Name&mc=mc_code&purpose=purpose_code&tr=transaction_record"
}
}
]
Payment link
"payment_settings": [
{
"type": "payment_link",
"payment_link": {
"uri": "https://the-payment-link"
}
}
]
Payment gateway (Razorpay)
"payment_settings": [
{
"type": "payment_gateway",
"payment_gateway": {
"type": "razorpay",
"configuration_name": "my-payment-config"
}
}
]

For a payment gateway, configuration_name is the name of your payment configuration and type is the provider.

order_details template​

An order details template lets you send the order details outside the customer service window. The order_details object is passed as the parameter of the template's order details button.

Example of an order_details template message

order_details template
{
"messages": {
"authentication": {
"productToken": "YOUR_PRODUCT_TOKEN"
},
"msg": [
{
"from": "00916098765432",
"to": [
{ "number": "00916012345678" }
],
"body": {
"type": "auto",
"content": "Here is your order summary."
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"element_name": "order_details_in_payments",
"language": { "policy": "deterministic", "code": "en" },
"components": [
{
"type": "header",
"parameters": [
{
"type": "image",
"media": {
"mediaUri": "https://www.example.com/images/order.png",
"mimeType": "image/png"
}
}
]
},
{
"type": "button",
"sub_type": "order_details",
"index": 0,
"parameters": [
{
"type": "action",
"action": {
"order_details": {
"reference_id": "F63F3F99",
"type": "digital-goods",
"payment_type": "upi",
"payment_configuration": "my-payment-config",
"currency": "INR",
"total_amount": { "value": 4000, "offset": 100 },
"payment_settings": [
{
"type": "upi_intent_link",
"upi_intent_link": {
"link": "upi://pay?pa=anything@payu&pn=ABC&tr=877376394&am=40.00&cu=INR&mode=00&purpose=00&mc=5399&tn=877376394"
}
}
],
"order": {
"status": "pending",
"items": [
{
"retailer_id": "42703ed5a",
"name": "Anker Speaker",
"amount": { "value": 4000, "offset": 100 },
"quantity": 1,
"country_of_origin": "India",
"importer_name": "CM.com",
"importer_address": {
"address_line1": "Saket District Centre, Sector 6, Pushp Vihar",
"city": "New Delhi",
"postal_code": "110017",
"country_code": "IN"
}
}
],
"subtotal": { "value": 4000, "offset": 100 },
"tax": { "value": 0, "offset": 100 },
"shipping": { "value": 0, "offset": 100 },
"discount": { "value": 0, "offset": 100 }
}
}
}
}
]
}
]
}
}
}
]
}
}
]
}
}

Update the order status​

Send an order_status message whenever the status of an order changes, for example when you receive the payment or ship the order.

Order statuses​

StatusUse when…
pendingThe order has been created. This is the initial status.
processingYou have received the payment.
shipped / partially-shippedPhysical goods are in transit.
completedThe service has been delivered or the item has arrived.
canceledThe order is cancelled. Only possible before payment is captured.

Payment statuses​

StatusEffect
pendingThe payment is pending.
capturedA green Paid label with a tick is added to the user's order bubble.
failedThe user is told the payment did not go through.
Best practices
  • Use the expiration object in order_details for time-sensitive offers or limited stock. When the order expires, the pay button is disabled automatically.
  • Use WhatsApp formatting in the body text to highlight important information, for example: Please complete your UPI payment within 15 minutes.

Interactive order_status message​

FieldRequiredDescription
interactive.typeYesorder_status
body.textYesMessage text.
action.nameYesreview_order
parameters.reference_idYesThe reference_id of the order.
parameters.order.statusYesThe new order status.
parameters.order.descriptionNoExplanation shown to the user.
Interactive order_status
{
"messages": {
"authentication": {
"productToken": "YOUR_PRODUCT_TOKEN"
},
"msg": [
{
"from": "00916098765432",
"to": [
{ "number": "00916012345678" }
],
"body": {
"type": "auto",
"content": "Your order status has been updated."
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"interactive": {
"type": "order_status",
"body": {
"text": "This is the status of your order."
},
"action": {
"name": "review_order",
"parameters": {
"reference_id": "F63F3F99",
"order": {
"status": "pending",
"description": "Order will be cancelled if not paid by the expiration time."
}
}
}
}
}
]
}
}
]
}
}

order_status template​

order_status template
{
"messages": {
"authentication": {
"productToken": "YOUR_PRODUCT_TOKEN"
},
"msg": [
{
"from": "00916098765432",
"to": [
{ "number": "00916012345678" }
],
"body": {
"type": "auto",
"content": "Your order status has been updated."
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"template": {
"whatsapp": {
"element_name": "order_status_in_payments",
"language": { "policy": "deterministic", "code": "en" },
"components": [
{
"type": "order_status",
"parameters": [
{
"type": "order_status",
"order_status": {
"reference_id": "F63F3F99",
"order": {
"status": "processing",
"description": "Thanks for your order. We are working on it!"
}
}
}
]
}
]
}
}
}
]
}
}
]
}
}

Example of an order_status message