Skip to content
Whats91

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

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.

POST/api/v2/orders/{orderUid}/send

Send the payment request for an existing order.

ParameterTypeRequiredDescription
orderUidstringRequiredOrder UID to send.
sender_idstringOptionalWhatsApp sender that owns the order.
config_uidstringOptionalExplicit active payment configuration for the sender. Defaults to the sender default configuration.
template_namestringOptionalApproved template containing an ORDER_DETAILS button. Required when the 24-hour service window is closed.
template_languagestringOptionalLanguage code for template_name.
body_textstringOptionalInteractive message body, maximum 1024 characters.
expires_in_minutesintegerOptionalPayment request expiry, 5 to 10080 minutes.
cURL
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
  }'
200 OK (data.payment_request)
{
  "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.

ErrorRetry action
PAYMENT_TEMPLATE_REQUIREDPick an eligible template from details.templates, then retry this endpoint.
PAYMENT_REQUEST_ACTIVE_EXISTSDo not create another intent. Read the order and inspect its payment state.
PAYMENT_META_SEND_OUTCOME_UNKNOWNDo not resend. Poll GET /api/v2/orders/{orderUid} and reconcile.
HTTP 502 with details.retryable: trueRetry this endpoint; the payment service reuses the safe draft intent and reference.
PAYMENTS_DISABLEDStop sending. The platform payment kill switch is active.

SDK Examples

Use these examples as starting points for server-side implementations.

cURL
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
}'
Node.js
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);
PHP
$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;
Python
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())
C#
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