Skip to main content

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:

  1. Create a Customer using the Customers API and save the returned id.
  2. Create a Mandate for that customer and save the returned id.
  3. Make the first payment, passing the Apple Pay token alongside the customerId and mandateId.
  4. For all subsequent payments, use only the customerId and mandateId — 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
}'
ParameterTypeDescription
methodstringThe payment method for the mandate. Currently "applepay" only.
maximumAmountPerPayment.valuestringThe maximum amount (in QAR) that can be charged per payment.
expiryDatestringThe date after which the mandate can no longer be used (YYYY-MM-DD).
numberOfPaymentsintegerThe 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.