Accept an Alternative Payment
This guide covers hosted redirect payments through payment sessions, using Paysafecard (psc) as the payment method. The customer completes the payment on the provider's hosted page instead of entering details on your site, so no card or voucher data ever touches your integration.
Creating a session also creates a linked transaction. The transaction follows the standard transaction lifecycle and emits the standard webhook events, so payment sessions plug into the same confirmation machinery as card payments.
For a walkthrough of the Paysafecard flow party by party, with a diagram, see Paysafecard via Skrill: Customer Journey.
Before you start
- You need an API key. Send it on every request as
Authorization: Bearer {YOUR_API_KEY}. - All examples use the sandbox base URL
https://api.sandbox.softlemons.com. - Redirect payments and the specific payment method must be enabled for your account. Requests for a method that is not enabled fail with
ERR_PAYMENT_METHOD_NOT_ENABLED. Contact support to get a method enabled. - Each method is only available in certain countries, and the provider risk-checks the customer's IP. Send
customer.country_codeandcustomer.ip_addresson every session. See Availability below. - Send
customer.emailtoo. For Paysafecard, Skrill uses it to take the customer straight to paysafecard's page instead of showing its own checkout form first. - You need two browser URLs on your site: a success URL and a cancel URL for the customer's return.
- Amounts are major units in requests (
25.00) and minor units in responses (2500). See conventions. - Never send card fields. A session request carrying card, token, CVV or voucher data is rejected with HTTP 422 regardless of where the field appears in the payload.
Step 1: Create a payment session
Call POST /api/v1/payment-sessions with the amount, a unique reference, the payment method and your return URLs:
JSON
The response gives you everything the flow needs:
payment_session_ididentifies the session in later status calls.checkout_urlis the provider's hosted page for this payment. Send the customer there in Step 2.transaction_idis the linked transaction. Webhook events reference it.expires_atis 15 minutes after creation. An unfinished session expires at that point.- The request field
success_urlcomes back asreturn_urlon the session.
The reference must be unique and duplicate protection applies. Reusing a reference that has an active session or transaction returns HTTP 409.
Partner API keys create sessions on behalf of a linked merchant by adding merchant_id to the body, with the same rules as partner card payments.
Two customer fields deserve special care:
customer.country_codeis the customer's country. It is checked against the method's availability before anything is sent to the provider (see Availability).customer.ip_addressis the customer's IP address as your server saw it, IPv4 or IPv6. Your call to this API is server-to-server, so without this field the provider only ever sees the IP of your server. Pass the value you actually observed and never a substitute: it is your attestation about the customer, and the provider uses it for its risk decision.
Step 2: Redirect the customer
Send the customer's browser to checkout_url. This is a full page redirect, not an iframe. The customer confirms the payment on the provider's page, for Paysafecard by entering their voucher PIN there.
The session stays pending_redirect while the customer is on the hosted page. It only changes when the provider reports back: pending_provider if the provider says the payment is still in progress, otherwise straight to paid, failed or cancelled. If the customer does not finish within 15 minutes the session becomes expired and you need to create a new one.
Step 3: Handle the browser return
After the hosted page the provider sends the customer back through the gateway, which immediately redirects the browser to your success_url or cancel_url with three query parameters appended:
TEXT
Treat this landing as navigation only. It tells you which session the customer came back from, never whether money moved. Confirmation of the provider's outcome can arrive before or after the browser does, so render a waiting state and resolve it in Step 4. Customers who close the tab never hit your return URL at all and the outcome still arrives by webhook.
Step 4: Confirm the outcome
The reliable signal is the webhook on the linked transaction. When the provider confirms the payment the session becomes paid and its transaction becomes captured, which delivers transaction.captured to your webhook endpoint. A failed payment delivers transaction.failed and an abandoned or expired session delivers transaction.cancelled.
To resolve a waiting page or reconcile on demand, poll the session:
JSON
Credit the customer only when the session is paid or the transaction.captured webhook arrives. The full session lifecycle (created, pending_redirect, pending_provider, paid, failed, cancelled, chargeback, expired) is documented in the statuses reference.
Availability
Alternative payment methods are not available everywhere. Two checks decide whether a session can be opened:
- Country. Each method has a list of countries it can serve. For Paysafecard (
psc) that is paysafecard's published availability (most of Europe plus, among others, Australia, Canada, Mexico, New Zealand, the United Kingdom and the United States; not, for example, South Africa or Costa Rica). Your account may carry a narrower list. The check runs oncustomer.country_codebefore the provider is contacted, and a country the method does not serve is refused with HTTP 400ERR_PAYMENT_METHOD_NOT_AVAILABLE_IN_COUNTRY. Nothing is created and thereferencestays free. If you do not sendcustomer.country_codethe check is skipped and the provider decides on its hosted page. - Provider risk rules on the customer's IP. The provider risk-checks the IP it receives as the customer's device IP. That IP is
customer.ip_addresswhen you send it, and the IP of the server calling this API when you do not. A server in a country the method does not serve therefore gets every payment refused unless it forwards the real customer IP. When the provider declines to open the checkout, the session fails with HTTP 400ERR_PROVIDER_REJECTED, themessagecarries the provider's reason (for exampleThe transaction has been blocked), the linked transaction isfailedwith the samestatus_reason, and thereferenceis released.
To avoid surprises, always send both customer.country_code and customer.ip_address, and offer the customer another method when you receive either code. Neither check creates a provider payment, so they are safe to hit as often as your checkout needs.
Ask before you show a method
GET /api/v1/payment-methods answers the same questions ahead of time so your checkout only shows methods that can actually be opened. Pass the customer's country and the payment currency; partner keys add merchant_id.
JSON
Each row is a redirect method enabled for the account. supported_countries and supported_currencies are the restrictions in force for it (an empty list means no restriction is known), and when you pass filters available tells you whether a session for that customer would be accepted, with unavailable_reasons being one or more of country_not_supported, currency_not_supported and provider_not_offering. A method that is available: false here would be refused by POST /api/v1/payment-sessions with the matching error. The endpoint reads configuration and the provider's published catalogue only; it never opens a provider payment, so call it per checkout if you like. It is advisory: the session create still runs the full provider checks, and card payments are not listed because they are governed by your acquirer routing rather than by this list.
Errors you should handle
| Response | Meaning | What to do |
|---|---|---|
400 ERR_PAYMENT_METHOD_NOT_ENABLED | The method or currency is not enabled for the merchant. | Offer a different payment method or contact support about enablement. |
400 ERR_PAYMENT_METHOD_NOT_AVAILABLE_IN_COUNTRY | The method is not available for customer.country_code. Checked before the provider is called; nothing is created. | Offer a different payment method for that country. See Availability. |
400 ERR_PROVIDER_REJECTED | The provider refused to open the payment for this customer (risk or availability rules, typically the customer's country or IP). message carries the provider's reason. The session and transaction are marked failed and the reference is released. | Make sure you send the real customer.ip_address and customer.country_code. Do not retry the same data blindly; offer another method. |
409 ERR_DUPLICATE | A session or transaction with this reference already exists. | Fetch the existing session instead of retrying. See duplicate protection. |
422 ERR_VALIDATION_FAILED | A field failed validation. This includes any request carrying card, token, CVV or voucher data, and a customer.ip_address that is not a valid IP. | Fix the request. Card data never belongs in a redirect session. |
429 ERR_RATE_LIMITED | Too many requests. | Back off and retry. See rate limits. |
502 ERR_GATEWAY_ERROR | The provider could not prepare the hosted session. The session and its transaction are marked failed. | Create a new session to retry. |
Full details for every code are in the error catalogue.