Create and send the exact-amount WhatsApp payment request for an existing draft order.
Send Order
Summary
Create and send the exact-amount WhatsApp payment request for an existing draft order.
Prerequisites
- Authorization: Bearer w91_live_xxx
- Content-Type: application/json for JSON requests
Related documentation
Creates the configured exact-amount payment intent for an existing order and submits the WhatsApp order_details message. This is the retry-safe endpoint: use it whenever a create-and-send call failed at the send step.
/api/v2/orders/{orderUid}/sendSend the payment request for an existing order.
| Parameter | Type | Required | Description |
|---|---|---|---|
orderUid | string | Required | Order UID to send. |
sender_id | string | Optional | WhatsApp sender that owns the order. |
config_uid | string | Optional | Explicit active payment configuration for the sender. Defaults to the sender default configuration. |
template_name | string | Optional | Approved template containing an ORDER_DETAILS button. Required when the 24-hour service window is closed. |
template_language | string | Optional | Language code for template_name. |
body_text | string | Optional | Interactive message body, maximum 1024 characters. |
expires_in_minutes | integer | Optional | Payment request expiry, 5 to 10080 minutes. |
curl -X POST "https://graph.whats91.com/api/v2/orders/ord_abc123/send" \
-H "Authorization: Bearer w91_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"sender_id": "919999999999",
"config_uid": "pcfg_manual_upi",
"body_text": "Please review and pay for your order.",
"expires_in_minutes": 30
}'{
"uid": "pay_abc123",
"order_uid": "ord_abc123",
"provider_config_uid": "pcfg_manual_upi",
"provider_code": "direct_upi_manual",
"mode": "UPI_INTENT",
"reference_id": "pay_abc123",
"amount_value": 30000,
"currency": "INR",
"status": "initiated",
"provider_order_id": null,
"provider_payment_id": null,
"meta_message_id": "wamid.example",
"message_status": "accepted",
"send_channel": "interactive",
"expires_at": "2026-08-06T10:00:00.000Z",
"paid_at": null,
"failed_at": null,
"failure_code": null,
"failure_reason": null,
"reconciliation": null,
"flags": {
"manual_confirmation": true,
"automatic_status_fetch": false
}
}Important
For Manual UPI, delivering the payment request does not mean payment was received. The order stays unpaid until an authorised business user verifies the transfer through the audited Mark as Paid action.
The payment DTO never includes UPI intent links, provider reference payloads, credentials, access tokens, or webhook secrets.
Send Safety
This endpoint does not use the idempotency ledger. It relies on the per-order payment lock, the unique active-payment-request constraint, stable provider reference reuse, the recorded Meta message id, and the send-outcome-unknown guard.
| Error | Retry action |
|---|---|
| PAYMENT_TEMPLATE_REQUIRED | Pick an eligible template from details.templates, then retry this endpoint. |
| PAYMENT_REQUEST_ACTIVE_EXISTS | Do not create another intent. Read the order and inspect its payment state. |
| PAYMENT_META_SEND_OUTCOME_UNKNOWN | Do not resend. Poll GET /api/v2/orders/{orderUid} and reconcile. |
| HTTP 502 with details.retryable: true | Retry this endpoint; the payment service reuses the safe draft intent and reference. |
| PAYMENTS_DISABLED | Stop sending. The platform payment kill switch is active. |
SDK Examples
Use these examples as starting points for server-side implementations.
curl -X POST "https://graph.whats91.com/api/v2/orders/{orderUid}/send" \
-H "Authorization: Bearer w91_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"sender_id": "919999999999",
"config_uid": "pcfg_manual_upi",
"body_text": "Please review and pay for your order.",
"expires_in_minutes": 30
}'const response = await fetch("https://graph.whats91.com/api/v2/orders/{orderUid}/send", {
method: "POST",
headers: {
"Authorization": "Bearer w91_live_xxx",
"Content-Type": "application/json"
},
body: JSON.stringify({
"sender_id": "919999999999",
"config_uid": "pcfg_manual_upi",
"body_text": "Please review and pay for your order.",
"expires_in_minutes": 30
})
});
const data = await response.json();
console.log(data);$ch = curl_init("https://graph.whats91.com/api/v2/orders/{orderUid}/send");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer w91_live_xxx",
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode([
"sender_id" => "919999999999",
"config_uid" => "pcfg_manual_upi",
"body_text" => "Please review and pay for your order.",
"expires_in_minutes" => 30
])
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;import requests
response = requests.request(
"POST",
"https://graph.whats91.com/api/v2/orders/{orderUid}/send",
headers={
"Authorization": "Bearer w91_live_xxx",
"Content-Type": "application/json",
},
json={
"sender_id": "919999999999",
"config_uid": "pcfg_manual_upi",
"body_text": "Please review and pay for your order.",
"expires_in_minutes": 30
}
)
print(response.json())using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer w91_live_xxx");
var request = new HttpRequestMessage(HttpMethod.Post, "https://graph.whats91.com/api/v2/orders/{orderUid}/send");
request.Content = new StringContent(
"""
{
"sender_id": "919999999999",
"config_uid": "pcfg_manual_upi",
"body_text": "Please review and pay for your order.",
"expires_in_minutes": 30
}
""",
Encoding.UTF8,
"application/json"
);
var response = await client.SendAsync(request);
Console.WriteLine(await response.Content.ReadAsStringAsync());Related APIs
Orders
Create a merchant draft order with catalog products or custom items.
List Orders
List and search orders for one sender with status, payment, source, and date filters.
Get Order
Read one tenant- and sender-scoped order with items, charges, events, payment, and readiness.
Create and Send
Create an order and send its payment request in one call, with idempotency protection.