Mandates API
Mandates allow you to charge a customer's payment method on a recurring basis without requiring them to re-authorize each transaction. Once a mandate is established, you can initiate subsequent payments server-to-server with no customer interaction required.
info
Mandates are currently supported for Apple Pay only. To use this feature, please contact Dibsy Customer Success Team.
tip
Only use mandates when your customer has given clear consent to be charged on a recurring basis. Always notify them before and after each charge to reduce your risk of chargebacks.
Overview
Setting up recurring payments with mandates involves a few additional steps compared to one-off payments:
- Create a Customer using the Customers API and save the returned
id. - Create a Mandate for that customer and save the returned
id. - Make the first payment, passing the Apple Pay token alongside the
customerIdandmandateId. - For all subsequent payments, use only the
customerIdandmandateId— no token required.
Step 1 — Create a Customer
All recurring payments require a customer record. If you don't already have one, create a customer using the Customers API and save the id to your database.
Request
curl --location --request POST 'https://api.dibsy.one/v2/customers' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk_live_mpmEeSyDEnRkXW6qakbhebjadg' \
--data-raw '{
"name": "Randy Marsh",
"email": "randy.m@hotmail.com",
"phone": "+97433999911",
"customFields": {
"homeAddress": "South Park",
"country": "QA"
}
}'
Response
HTTP/1.1 201 Created
Content-Type: application/hal+json
{
"id": "cst_4qqhO89gsT",
"resource": "customer",
"name": "Randy Marsh",
"email": "randy.m@hotmail.com",
"phone": "+97433999911",
"organizationId": "300000",
"customFields": {
"country": "QA",
"homeAddress": "South Park"
},
"_links": {
"self": {
"href": "http://api.dibsy.one/v2/customers/cst_4qqhO89gsT",
"type": "application/hal+json"
},
"dashboard": {
"href": "https://dashboard.dibsy.one/customers/cst_4qqhO89gsT",
"type": "text/html"
},
"documentation": {
"href": "https://api.dibsy.dev//#operation/Create%20Customer",
"type": "text/html"
}
}
}
Step 2 — Create a Mandate
With a customer in place, create a mandate for them. The mandate defines the terms of the recurring agreement — the maximum charge per payment, how many payments are permitted, and when the mandate expires.
Request
curl --location --request POST 'https://api.dibsy.one/v2/customers/cst_4qqhO89gsT/mandates' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk_live_mpmEeSyDEnRkXW6qakbhebjadg' \
--data-raw '{
"method": "applepay",
"maximumAmountPerPayment": {
"value": "2.00"
},
"expiryDate": "2025-03-15",
"numberOfPayments": 3
}'
| Parameter | Type | Description |
|---|---|---|
method | string | The payment method for the mandate. Currently "applepay" only. |
maximumAmountPerPayment.value | string | The maximum amount (in QAR) that can be charged per payment. |
expiryDate | string | The date after which the mandate can no longer be used (YYYY-MM-DD). |
numberOfPayments | integer | The total number of payments permitted under this mandate. |
Response
HTTP/1.1 201 Created
Content-Type: application/json
{
"resource": "mandate",
"id": "mdt_h3gAaD5zP",
"status": "pending",
"customerId": "cst_4qqhO89gsT",
"method": "applepay",
"createdAt": "2025-05-07T10:49:08+00:00",
"_links": {
"self": {
"href": "https://api.dibsy.one/v2/customers/cst_4qqhO89gsT/mandates/mdt_h3gAaD5zP",
"type": "application/hal+json"
},
"customer": {
"href": "https://api.dibsy.one/v2/customers/cst_4qqhO89gsT",
"type": "application/hal+json"
}
}
}
The mandate is created with a status of pending. It becomes active after the first successful payment is made against it. Save the id to your database — you will need it for all subsequent payments.
Step 3 — Make the First Payment
For the initial payment, pass the Apple Pay token alongside the customerId and mandateId. Set sequenceType to "recurring".
Request
curl --location --request POST 'https://api.dibsy.one/v2/payments' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk_live_mpmEeSyDEnRkXW6qakbhebjadg' \
--data-raw '{
"amount": {
"value": "40.00",
"currency": "QAR"
},
"method": "applepay",
"sequenceType": "recurring",
"customerId": "cst_4qqhO89gsT",
"mandateId": "mdt_h3gAaD5zP",
"applePayToken": "{\"paymentData\":{\"data\":\"RShtfLLhk++/YNB...FMQ8XDTIzMDkxOTE0a23bec1d\"}}",
"description": "Order #1337",
"redirectUrl": "https://redirect.example.org/redirect"
}'
Response
{
"id": "pt_6CVWLUT7fxhbWZZS88",
"resource": "payment",
"mode": "live",
"amount": {
"value": "40.00",
"currency": "QAR"
},
"amountNet": {
"value": "38.50",
"currency": "QAR"
},
"amountRemaining": {
"value": "40.00",
"currency": "QAR"
},
"description": "Order #1337",
"method": "applepay",
"redirectUrl": "https://redirect.example.org/redirect",
"status": "succeeded",
"organizationId": "22858676",
"sequenceType": "recurring",
"customerId": "cst_4qqhO89gsT",
"mandateId": "mdt_h3gAaD5zP",
"createdAt": "2025-05-07T10:49:08+00:00",
"paidAt": "2025-05-07T10:49:08+00:00",
"_links": {
"self": {
"href": "https://api.dibsy.one/v2/payments/pt_6CVWLUT7fxhbWZZS88",
"type": "application/hal+json"
},
"dashboard": {
"href": "http://dashboard.dibsy.one/payments/pt_6CVWLUT7fxhbWZZS88",
"type": "text/html"
},
"documentation": {
"href": "http://api.dibsy.dev/#operation/Create%20Payment",
"type": "text/html"
}
}
}
Step 4 — Make Subsequent Payments
Once the first payment succeeds, the mandate becomes active. For all future charges, omit the applePayToken — only the customerId and mandateId are required. The customer is not prompted for any interaction.
Request
curl --location --request POST 'https://api.dibsy.one/v2/payments' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk_live_mpmEeSyDEnRkXW6qakbhebjadg' \
--data-raw '{
"amount": {
"value": "40.00",
"currency": "QAR"
},
"method": "applepay",
"sequenceType": "recurring",
"customerId": "cst_4qqhO89gsT",
"mandateId": "mdt_h3gAaD5zP",
"description": "Order #1338",
"redirectUrl": "https://redirect.example.org/redirect"
}'
Response
{
"id": "pt_7DWXMVU8gyhcXAAT99",
"resource": "payment",
"mode": "live",
"amount": {
"value": "40.00",
"currency": "QAR"
},
"amountNet": {
"value": "38.50",
"currency": "QAR"
},
"amountRemaining": {
"value": "40.00",
"currency": "QAR"
},
"description": "Order #1338",
"method": "applepay",
"redirectUrl": "https://redirect.example.org/redirect",
"status": "succeeded",
"organizationId": "22858676",
"sequenceType": "recurring",
"customerId": "cst_4qqhO89gsT",
"mandateId": "mdt_h3gAaD5zP",
"createdAt": "2025-05-07T11:00:00+00:00",
"paidAt": "2025-05-07T11:00:00+00:00",
"_links": {
"self": {
"href": "https://api.dibsy.one/v2/payments/pt_7DWXMVU8gyhcXAAT99",
"type": "application/hal+json"
},
"dashboard": {
"href": "http://dashboard.dibsy.one/payments/pt_7DWXMVU8gyhcXAAT99",
"type": "text/html"
},
"documentation": {
"href": "http://api.dibsy.dev/#operation/Create%20Payment",
"type": "text/html"
}
}
}
Client-Side Changes for Apple Pay (iOS)
When presenting the Apple Pay sheet for a recurring payment, include a recurringPaymentRequest in your PKPaymentRequest. This displays subscription details — price, frequency, and start date — directly in the Apple Pay sheet, giving customers full visibility before they authorize.
import PassKit
final class PayCoordinator: NSObject, PKPaymentAuthorizationControllerDelegate {
func presentApplePay() {
let req = PKPaymentRequest()
req.merchantIdentifier = "merchant.com.yourcompany.app"
req.countryCode = "QA"
req.currencyCode = "QAR"
req.supportedNetworks = [.visa, .masterCard, .amex]
req.merchantCapabilities = .capability3DS
let monthly = PKRecurringPaymentSummaryItem(
label: "Pro Plan — Monthly",
amount: NSDecimalNumber(string: "40.00")
)
monthly.startDate = ISO8601DateFormatter().date(from: "2025-09-01T00:00:00Z")
monthly.intervalUnit = .month
monthly.intervalCount = 1
let recurring = PKRecurringPaymentRequest(
paymentDescription: "Pro Plan subscription",
regularBilling: monthly,
managementURL: URL(string: "https://your.domain/account/billing")!
)
req.recurringPaymentRequest = recurring
let controller = PKPaymentAuthorizationController(paymentRequest: req)
controller.delegate = self
controller.present(completion: nil)
}
func paymentAuthorizationController(
_ controller: PKPaymentAuthorizationController,
didAuthorizePayment payment: PKPayment,
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void
) {
// Send payment.token to your backend to create the first payment
completion(.init(status: .success, errors: nil))
}
func paymentAuthorizationControllerDidFinish(_ controller: PKPaymentAuthorizationController) {
controller.dismiss(completion: nil)
}
}
Using recurringPaymentRequest provides several benefits: the Apple Pay sheet shows price, frequency, and start date transparently; card networks recognize the transaction as recurring which can improve approval rates; and Apple Wallet links customers to your billing page for easy subscription management.
For full details, see Apple's documentation on PKRecurringPaymentRequest.