Create a Payment Intent
The one server-side call that starts a Flow session and returns a browser-safe token.
A Payment Intent starts a Flow session. You create it from your backend with your secret API key. In the request, give the agreement and the payment you want to take. The response is the first Result: a token and the first action for the widget to run.
This is the only call you make directly. The widget makes every call after it.
Create the intent
POST /embed/create-payment-intent
Authorization: Bearer <your-secret-api-key>
Content-Type: application/jsonRequest Example
{
"client_id": "019efd1237de70d1b69bae4f1c48d170",
"type": "PayTo.Debtor.OneTimePayment",
"data": {
"agreement": {
"uid": "biz_agreement_G7MQWwkQZIP8vbfH",
"purpose": "retail",
"description": "Payment plan for order #1234",
"creditor": {
"party_name": "Zeptinghouse Pty Ltd",
"ultimate_party_name": "Zeptinghouse Pty Ltd",
"account_identifier": {
"type": "bban",
"bsb": "062000",
"account_number": "12345678"
}
}
},
"payment": {
"uid": "biz_20221231_G7MQWwkQZIP8vbfH",
"amount": 2495,
"reference": "Order 1234"
}
}
}Response 201
{
"token": "eyJhbGci…",
"action": {
"name": "collect-debtor-details",
"path": "/payto/debtor/one-time-payment/create-agreement"
}
}Return { token, action } to your checkout page and hand it to the widget. See Mount the widget.
The token is opaque and browser-safe
Treat token as an opaque string scoped to this one Payment Intent. Pass it to your page unchanged. Do not parse, log, or persist it beyond that.
Request fields
| Field | Required | Description |
|---|---|---|
client_id | Yes | Your client identifier: 32 characters, RFC 3986 unreserved characters (A-Z a-z 0-9 _ ~ . -). |
type | Yes | The flow to run. Currently PayTo.Debtor.OneTimePayment. |
data.agreement | Yes | The PayTo agreement to create. See below. |
data.payment | Yes | The payment to take against the agreement. See below. |
agreement
agreement| Field | Required | Description |
|---|---|---|
uid | Yes | Your unique identifier for the agreement (≤64 chars, RFC 3986 unreserved). Ensures uniqueness between your system and Zepto. |
purpose | Yes | Nature of the agreement: retail, loan, utility, mortgage, salary, personal, government, pension, tax, dependant_support, gambling, or other. |
description | Yes | Narrative reason for the agreement (≤140 chars, ASCII printable). |
creditor | Yes | The party that receives the payment: party_name, ultimate_party_name, and an account_identifier (see alias resolution when you use PayID). |
resolution_requested_before | No | ISO-8601 UTC deadline for the payer to accept. Defaults to 10 minutes from creation. |
cancel_if_unresolved | No | Auto-cancel if not authorised by resolution_requested_before. Needs that field to be set. |
metadata | No | Your custom data (flat object, ≤2 kb). Zepto echoes it in webhook payloads under resource_metadata. |
payment
payment| Field | Required | Description |
|---|---|---|
uid | Yes | Your unique identifier for the payment (≤64 chars, RFC 3986 unreserved). |
amount | Yes | Amount in cents (integer). 2495 is $24.95 AUD. |
reference | No | Free-form text for reconciliation. It usually appears on both parties' bank statements. |
description | No | Longer free-form text that helps to match the payment (≤280 chars). |
metadata | No | Your custom data (flat object, ≤2 kb). |
Amounts are in cents
amount is an integer number of cents, not dollars. Send 2495 for $24.95, not 24.95.
Validation errors
If the request is invalid, you get a 422 response. It contains an errors array that shows what to fix:
{
"errors": [
{ "title": "Invalid client_id", "detail": "The client_id provided is not valid", "code": "E100" }
]
}Next steps
Mount the widget with the { token, action } you just received.
Updated 6 days ago

