curl --request POST \
--url https://staging.api.payluk.ng/v1/payment/create-intent \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'customer-id: <customer-id>' \
--data '
{
"amount": 10000,
"reference": "99999533334",
"transactionType": "withdrawal",
"withdrawalDetails": {
"accountName": "EZUMAH JEREMIAH KALU",
"accountNumber": "3069839406",
"bankName": "First Bank Nigeria",
"bankCode": "011"
}
}
'{
"status": 200,
"message": "Payment intent created successfully",
"data": {
"id": "692838701c1a5da0bf1c2bad",
"amount": 10000,
"reference": "99999533334",
"fee": 100,
"transactionType": "withdrawal",
"currency": "NGN",
"transferDetails": null,
"depositDetails": null,
"walletDetails": null,
"withdrawalDetails": {
"bankCode": "011",
"accountNumber": "3069839406",
"accountName": "EZUMAH JEREMIAH KALU",
"bankName": "First Bank Nigeria"
},
"escrowDetails": null,
"metadata": null,
"status": "pending",
"creditType": "debit",
"createdAt": "2025-11-27T11:39:28.931Z",
"updatedAt": "2025-11-27T11:39:28.931Z"
}
}Create payment intent
Creates a payment intent for a merchant customer. Set transactionType to one of:
withdrawal: a payout. For a fiat bank withdrawal supplywithdrawalDetails(bank account); for a crypto transfer supplyblockchainDetails(recipient address + network) instead.deposit: a card top-up of the customer’s wallet. withdepositDetails.cardIdthe saved card is charged through Paystack (Nigerian customers only). Without a card the deposit becomes a hosted collection: on production the response carries acheckoutConfigfor the active gateway’s checkout, and on staging atestAccount(Payluk Test Bank details) to pay into; settle it with Verify payment once paid.wallet_transfer: send funds to another Payluk wallet viawalletDetails.
Card deposits
A deposit charges a saved (tokenized) card; it does not collect new card details. The cardId is the id of a card returned by List customer cards.
A customer only has saved cards when the merchant has the save-customer-cards feature enabled on their account. With it enabled, when a merchant customer pays with a card through Payluk’s inline checkout, Payluk tokenizes the card (stores its reusable payment authorization) against that customer. The tokenized card then appears in the cards list and can be charged here (via depositDetails.cardId) to top up the wallet without the customer re-entering card details.
Withdrawal fees
Payluk sets the fee on the returned intent; you do not send it. The customer is debited amount + fee, so reconcile against the fee you read back rather than assuming a figure.
The fee depends on the amount and on which provider Payluk currently settles payouts through, and it may include VAT. It is fixed on the intent when the intent is created, so the figure you read back is the figure that will be charged.
Two-step flow
Creating the intent only stages the transaction; no money moves yet. To execute it, submit the returned reference to Verify payment. This separation exists for security.
All field values are lowercase. Requires the customer-id header.
Amounts are naira with at most two decimal places; the minimum is 100 for a deposit or transfer. Bank payouts are routed to whichever provider Payluk currently settles through, and a crypto payout to blockchainDetails.toAddress on BSC; the gateway field is resolved server-side and can be omitted.
curl --request POST \
--url https://staging.api.payluk.ng/v1/payment/create-intent \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'customer-id: <customer-id>' \
--data '
{
"amount": 10000,
"reference": "99999533334",
"transactionType": "withdrawal",
"withdrawalDetails": {
"accountName": "EZUMAH JEREMIAH KALU",
"accountNumber": "3069839406",
"bankName": "First Bank Nigeria",
"bankCode": "011"
}
}
'{
"status": 200,
"message": "Payment intent created successfully",
"data": {
"id": "692838701c1a5da0bf1c2bad",
"amount": 10000,
"reference": "99999533334",
"fee": 100,
"transactionType": "withdrawal",
"currency": "NGN",
"transferDetails": null,
"depositDetails": null,
"walletDetails": null,
"withdrawalDetails": {
"bankCode": "011",
"accountNumber": "3069839406",
"accountName": "EZUMAH JEREMIAH KALU",
"bankName": "First Bank Nigeria"
},
"escrowDetails": null,
"metadata": null,
"status": "pending",
"creditType": "debit",
"createdAt": "2025-11-27T11:39:28.931Z",
"updatedAt": "2025-11-27T11:39:28.931Z"
}
}Authorizations
Your secret key as a Bearer token. The key prefix selects the environment: sk_test_... (staging) or sk_live_... (production); a key on the wrong host is refused with 403 Unauthorized Access. Each key is limited to 10 requests per minute (429 beyond that) and, on production, to the IP addresses on your dashboard allowlist when one is configured.
Headers
The merchant customer this request acts on behalf of.
Body
Amount in major units (NGN), not kobo: send 10000 for ₦10,000. Kobo are allowed as decimals (₦100.20 is 100.2) and are rounded to two places. Minimum 100, meaning ₦100.
x >= 10010000
Your unique reference for this transaction.
"99999533334"
Use withdrawal for both a fiat bank withdrawal (with withdrawalDetails) and a crypto transfer (with blockchainDetails).
withdrawal, deposit, wallet_transfer "withdrawal"
Optional. Defaults to NGN.
"NGN"
Required for a fiat bank withdrawal (transactionType: withdrawal).
Show child attributes
Show child attributes
Required for a crypto transfer (transactionType: withdrawal); supply this instead of withdrawalDetails.
Show child attributes
Show child attributes
Required for a wallet_transfer to another Payluk wallet.
Show child attributes
Show child attributes
Optional on a deposit. Names a saved card to charge; omit it to collect through a hosted checkout.
Show child attributes
Show child attributes
Response
Payment intent created.