Payment Handle operations for the Paysafe Payments API.
A Payment Handle is the entry point for every payment, payout, and
verification transaction. It tokenizes the customer's payment instrument
and must be created before calling /payments, /payouts, etc.
Handle lifecycle
INITIATED → (redirect if 3DS/APM) → PAYABLE → [used] → COMPLETED
↘ FAILED
↘ EXPIRED (after timeToLiveSeconds)Supported payment types
Cards, Apple Pay, Google Pay, PayPal, Venmo, Skrill, Skrill 1-Tap, Neteller, PaysafeCard, PaysafeCash, ACH, BACS, EFT, SEPA, iDEAL, Interac e-Transfer, Mazooma, Pay by Bank, VIP Preferred, Play+, Openbucks, BLIK, EPS, EFT, MB WAY, Multibanco, Rapid Transfer, SafetyPay, PagoEfectivo, and more.
Network Tokenization
Network Tokenization is not a separate API — it's accessed by passing
network token fields directly inside a card object on this same
create/3 call (or via the Customer Vault API). Replace card_num with
a network_token object:
Paysafe.Payments.PaymentHandles.create(config, %{
merchant_ref_num: "order-001",
amount: 5000,
currency_code: "USD",
payment_type: "CARD",
transaction_type: "PAYMENT",
card: %{
holder_name: "John Doe",
token_type: "NETWORK_TOKEN",
network_token: %{
token: "5200000000002151",
cryptogram: "MFNyroCRmAPANZWxrEK4TgACVUA=",
expiry: %{month: 10, year: 2025}
}
},
billing_details: %{street: "abcd", city: "defg", state: "AL", country: "US", zip: "94404"}
})This works for external network tokens (issued by another PSP or via
Visa/Mastercard Click to Pay) as well as Paysafe-managed tokens created
automatically when you save a card via the Customer Vault. Network tokens
have three lifecycle states (ACTIVE, SUSPENDED, DELETED) reflected in
the status field of the networkToken object on responses — see
Paysafe.Payments.Customers for saved-card lookups.
Examples
# Card payment handle (no 3DS)
Paysafe.Payments.PaymentHandles.create(config, %{
merchant_ref_num: "order-001",
amount: 5000,
currency_code: "USD",
payment_type: "CARD",
transaction_type: "PAYMENT",
card: %{
card_num: "4111111111111111",
card_expiry: %{month: 12, year: 2030},
cvv: "123",
holder_name: "Jane Doe"
},
billing_details: %{
street: "123 Main St",
city: "New York",
state: "NY",
country: "US",
zip: "10001"
}
})
Summary
Functions
@spec create(Paysafe.Config.t(), map(), keyword()) :: {:ok, Paysafe.Types.PaymentHandle.t()} | {:error, Paysafe.Error.t()}
Create a Payment Handle.
Parameters
:merchant_ref_num(required) — Your unique reference number. Acts as the idempotency key.:amount(required) — Amount in minor units (e.g. 5000 = $50.00).:currency_code(required) — ISO 4217 currency code.:payment_type(required) — One of"CARD","PAYPAL","SKRILL","NETELLER","PAYSAFECARD","PAYSAFECASH","ACH","BACS","EFT","SEPA","IDEAL","INTERAC","VENMO","APPLE_PAY","GOOGLE_PAY", etc.:transaction_type(required) —"PAYMENT","STANDALONE_CREDIT","ORIGINAL_CREDIT", or"VERIFICATION".:account_id— Paysafe account ID. Required only if your API key has multiple accounts configured for the same payment method/currency combination; omit otherwise. Sent in the request body, not the URL.:return_links— Required for redirect-based payment methods.:card— Card object (required forpayment_type: "CARD").:three_ds— 3DS authentication object.:billing_details— Customer billing address.:profile— Customer profile.:merchant_descriptor— Dynamic descriptor shown on cardholder statement.:customer_ip— Customer's IP address.:device_fingerprint_id— Device fingerprint for fraud detection.
Returns {:ok, %PaymentHandle{}} or {:error, %Error{}}.
Notes
- Always check
time_to_live_secondsin the response to know your handle's exact TTL. - If
action == :redirect, redirect the customer to the URL inlinksbefore calling/payments. - For async payment methods (PaysafeCash, some APMs), subscribe to webhooks.
@spec get(Paysafe.Config.t(), String.t(), keyword()) :: {:ok, Paysafe.Types.PaymentHandle.t()} | {:error, Paysafe.Error.t()}
Retrieve a Payment Handle by ID.
Useful for polling status if webhooks are not received. Use in combination with webhooks — always verify via GET after receiving a webhook.