Payments
You choose how to pay when you confirm a booking. Quoting never charges anything. The confirm request names a payment method, Transdirect charges it, and the booking goes to the courier.
{ "courier": "couriers_please", "pickup_date": "2026-10-19", "payment_method": "nab_4821"}Payment methods
Section titled “Payment methods”Send one of these as payment_method in the confirm body:
payment_method | Pays with |
|---|---|
nab_<id> | A credit card saved in your account |
paypal_<id> | A PayPal account linked to your account |
credit | Your Transdirect credit account, if you have one |
demo | Nothing. Use with the demo courier to test without charge. |
Take nab_<id> and paypal_<id> values exactly as list payment methods returns them. Raw card numbers, CVVs and expiry dates are never accepted by the API.
If you leave payment out, Transdirect bills your credit account, the same as credit. Most accounts do not have one, so name the method you want every time.
You can send the same choice as a structured payment object instead, for example {"method": "card", "card_id": 4821}. See confirm a booking. Use one form or the other; if you send both they must agree.
Saved cards and PayPal
Section titled “Saved cards and PayPal”Cards and PayPal accounts are added in the members area, not through the API:
- Sign in at members.transdirect.com.au.
- Open Settings, then Payment Methods (or use the Payment Methods button on Billing).
- Choose Add a card or Add PayPal and follow the prompts.
Then list them from your integration:
curl https://api.transdirect.com.au/api/v5/members/payment-methods \ -H "api-key: $TD_API_KEY"[ { "id": "nab_4821", "type": "credit_card", "masked_label": "VISA ending 444433......1111", "is_default": true }, { "id": "paypal_377", "type": "paypal", "masked_label": "PayPal (accounts@example.com)", "is_default": false }]Pass the id as payment_method. Having a default card is not enough on its own: the API charges a saved method only when the confirm request names it. The list does not check card expiry, so an expired card is still listed; charging it at confirm normally fails with a 402.
Credit account
Section titled “Credit account”A credit account lets you confirm bookings now and pay them on an invoice. It is optional. To apply, open Payment Methods in the members area and choose Apply for Credit Account.
Once your account has credit, GET /api/v5/member shows credit_limit above 0 and credit_limit_available as the amount left. Confirm with "payment_method": "credit".
Pay at end of day
Section titled “Pay at end of day”Pay at end of day lets an account confirm card or PayPal bookings during the day and be charged for them together at 9pm Sydney time, in one charge per card or PayPal account. Bookings are lodged with the courier and labelled straight away, as for any paid booking. If your account has it, the members area booking screen shows a Pay at end of day option. To have it switched on for your account, contact Transdirect support.
To use it from the API, add "batch": true to a confirm that pays by card or PayPal:
{ "courier": "couriers_please", "pickup_date": "2026-10-19", "payment_method": "nab_4821", "batch": true}The booking is confirmed and its status moves to paid as usual. In these cases the booking is charged straight away instead, with no error:
- Pay at end of day is not on for your account.
- It is 9pm Sydney time or later.
- The booking would take the day’s uncharged total over your account’s daily Pay at end of day limit.
- Pay at end of day is paused for your account because an earlier 9pm charge was declined.
A top-level batch has no effect on credit or demo. If the 9pm charge is declined, Pay at end of day is paused for your account and the members area asks you to pay the day’s total (Pay now on Payment Methods). Until then, bookings are charged straight away.
How much is charged
Section titled “How much is charged”When you confirm, Transdirect prices the booking again from its current details and charges that amount, including GST. It normally matches the total of the quote you chose. If you changed items or addresses since quoting, quote again before you show your customer a price.
Payment errors
Section titled “Payment errors”402: the payment failed
Section titled “402: the payment failed”The payment could not be completed. The gateway may have declined the charge, or the payment could not start (for example the saved card was not found), so a 402 does not always mean a charge was attempted. Nothing was charged unless payment_error.code says otherwise (see the two codes below). Check payment_error.code, show payment_error.user_message, and let the customer choose another method.
{ "errors": { "payment": ["Your card was declined. Please try another payment method."] }, "payment_error": { "code": "CARD_DECLINED", "user_message": "Your card was declined. Please try another payment method.", "log_id": 918273, "method": "card" }}Common payment_error.code values:
| Code | Meaning |
|---|---|
CARD_DECLINED | The bank declined the card. |
CARD_NOT_FOUND | The nab_<id> is not an active card on your account. List payment methods again. |
AGREEMENT_NOT_FOUND | The paypal_<id> is not an active PayPal agreement on your account. |
AGREEMENT_REVOKED | The PayPal agreement is no longer active. Re-link PayPal in the members area. |
GATEWAY_TIMEOUT | The payment gateway could not be reached. Try again shortly. |
EOD_QUEUE_LOCKED | The booking is already being added to today’s Pay at end of day charge. Get the booking before retrying. |
Check before you retry. A 402 that also contains error and booking_id means the payment may have gone through:
{ "error": "Booking payment requires recovery.", "booking_id": 623630, "errors": { "payment": ["Payment could not be confirmed. Do not pay again or create another booking. Contact Transdirect support with this booking ID."] }, "payment_error": { "code": "GATEWAY_INDETERMINATE", "user_message": "Payment could not be confirmed. Do not pay again or create another booking. Contact Transdirect support with this booking ID.", "method": "card", "log_id": null }}GATEWAY_INDETERMINATE: the charge may have been taken. Do not retry, pay again or create another booking; contact Transdirect support with thebooking_id.PAYMENT_FINALISATION_PENDING: the payment was captured but confirmation did not finish. Send the same confirm again for the samebooking_id, with the samepayment_method. When the payment type and amount still match the captured payment, the retry reuses it and completes the booking without charging again. If it does not complete, contact Transdirect support with thebooking_idrather than paying another way.
403: nothing was charged
Section titled “403: nothing was charged”The confirm was refused before any charge. The body has an error message and an access_error.code:
{ "error": "Add a payment method or set up a credit account to make a live booking.", "access_error": { "code": "NO_PAYMENT_METHOD", "user_message": "Add a payment method or set up a credit account to make a live booking." }}access_error.code | What to do |
|---|---|
NO_PAYMENT_METHOD | You confirmed with credit (or no payment) and the account has no credit account. Send a saved payment_method, or use demo while testing. |
CREDIT_LIMIT_REACHED | The booking would take your credit account past its limit. Pay an outstanding invoice, or send a saved payment_method instead. |
API_ACCESS_DISABLED | API booking has been switched off for this account. Contact Transdirect support. |
400: the request was invalid
Section titled “400: the request was invalid”A payment_method that does not match demo, credit, nab_<id> or paypal_<id> is rejected with a validation error rather than ignored, so a typo can never fall back to your credit account. Raw card fields such as card_number or cvv are rejected the same way.
Retrying a confirm safely
Section titled “Retrying a confirm safely”Network errors happen. A confirm that names a payment method is safe to send again: if the first attempt already paid for the booking, the retry returns 204 and nothing is charged twice.
A confirm without a payment method is not: once the booking is paid, a repeat returns 400 {"errors":["Cannot update. Booking has been processed."]}. That also tells you the first attempt succeeded. Either way, get the booking and check is_paid and status_code before you try anything else.