# Deadlines Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/deadlines Response deadlines and the consequences of missing them. ## Deadline and consequences * Deadline to submit evidence **varies per dispute**. Please refer to the dashboard for the specific deadline mentioned on each dispute case. **What happens if you miss it:** * Dispute is automatically lost. * Disputes affect your merchant performance score. Always respond before the stated deadline on the dashboard to avoid automatic loss. # Overview Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/dispute-management What disputes are, where to track them, and how you're notified. ## What is a dispute? A **dispute** is raised when a customer challenges a transaction through their issuing bank instead of contacting you directly. The bank reverses the payment (chargeback) while it investigates and asks you to prove the charge was valid. When a dispute is raised, Partner banks holds the disputed amount from your balance and notifies you to respond. If you submit evidence that supports the charge and win, the funds are returned. If you don't respond by the deadline, or the bank rules against you, the dispute is lost and the amount stays deducted. Responding on time with clear, relevant evidence is the single biggest factor in winning a dispute. This section walks you through every step. ## Where to see disputes Disputes are managed from the xPay Dashboard. * **Path**: [Dashboard → Disputes](https://app.xpaycheckout.com/disputes) * Each dispute shows its current status, the reason for the challenge, the disputed amount, and the response deadline. An active dispute awaiting your response has the status `DISPUTED`. ## How you're notified When a dispute is raised on one of your transactions, xPay alerts you through: * **Email** — sent to your registered account contacts * **Dashboard** — the dispute appears under [Dashboard → Disputes](https://app.xpaycheckout.com/disputes) * **Webhooks** — subscribe to the [dispute events](/developer-resources/webhooks/events/intentEvents/disputed) to track disputes programmatically *** ## Explore this section   How disputes work } href="/dashboard-operations/dispute-management/how-disputes-work"> The dispute lifecycle, from a customer complaint to a final outcome.   Deadlines } href="/dashboard-operations/dispute-management/deadlines"> Response deadlines and what happens if you miss them.   Reason codes } href="/dashboard-operations/dispute-management/reason-codes"> What each dispute reason code means across card, bank, ACH, and check.   Responding by reason } href="/dashboard-operations/dispute-management/responding-by-reason"> How to fight or accept each reason, and the evidence that wins.   Evidence guidelines } href="/dashboard-operations/dispute-management/evidence-guidelines"> How to submit evidence, and how to respond to or accept a dispute.   Reducing disputes } href="/dashboard-operations/dispute-management/reducing-disputes"> Best practices to prevent disputes before they happen. # Evidence guidelines Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/evidence-guidelines How to submit evidence, and how to respond to or accept a dispute. Submit clear and relevant proof to support your case. **Guidelines:** * Upload clear, legible documents that support your case * **Mandatory evidence documents**: Customer communication and payment invoice * Include any other relevant evidence based on the dispute reason, such as your refund policy, service records, or activity logs * Ensure all the evidence is properly labeled **Upload Process:** * Navigate to `Dashboard → Disputes → Open Dispute -> Counter Dispute` **Accept Dispute:** * Navigate to `Dashboard → Disputes → Open Dispute -> Accept Dispute` Accepting a dispute will result in losing the dispute and funds being permanently deducted. # Dispute FAQ Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/faq Common questions about handling disputes. ### Should I respond to every dispute? > No. Respond only when you have evidence that rebuts the specific claim. If the claim is fair, accepting avoids extra fees and protects your standing. ### What documents are always required? > Customer communication and the payment invoice, on every counter-dispute. ### What happens if I miss the deadline? > The dispute is automatically lost, funds are permanently deducted, and your performance score is affected. ### I already refunded the customer — is the dispute closed? > Open the dispute and submit the refund evidence (reference, date, amount) as your counter-dispute. ### Do I get my money back if I win? > Yes. The amount withdrawn when the dispute was raised is credited back when you win. # How disputes work Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/how-disputes-work The dispute lifecycle, from a customer complaint to a final outcome. ## How a dispute occurs 1. Customer raises a complaint with their bank. 2. The bank initiates a chargeback request. 3. xPay marks the transaction as **DISPUTED**. 4. Funds are held until resolution. 5. Merchant is notified to respond with evidence. A timely and thorough response increases the chances of reversing the chargeback. ## Dispute status lifecycle ```mermaid theme={null} graph LR A[DISPUTED] --> B[DISPUTE_UNDER_REVIEW] B --> C{Outcome} C -->|DISPUTE_WON| D[Funds Released] C -->|DISPUTE_LOST| E[Funds Deducted] ``` **Status Definitions:** | Status | Description | | ---------------------- | ------------------------------------------------------------ | | `DISPUTED` | A dispute has been raised and is awaiting merchant action. | | `DISPUTE_UNDER_REVIEW` | Evidence submitted; the bank is reviewing the case. | | `DISPUTE_WON` | The bank ruled in your favor — funds are returned. | | `DISPUTE_LOST` | The bank ruled against you — funds are permanently deducted. | All status changes are visible in real-time in the dashboard. # Network code reference Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/network-code-reference Map the underlying Visa, Mastercard, and American Express network codes to xPay dispute categories. The underlying card networks use their own numeric codes. These tables map them to the xPay categories, so when you see a raw network code you can find the matching xPay reason. | **xPay category** | **Visa codes** | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `credit_not_processed` | • 13.6 credit not processed
• 13.7 cancelled merchandise / services | | `duplicate` | • 12.6.1 duplicate processing
• 12.6.2 paid by other means | | `fraudulent` | • 10.1 EMV liability shift – counterfeit
• 10.2 EMV liability shift – non-counterfeit
• 10.3 other fraud – card present
• 10.4 other fraud – card absent
• 10.5 fraud monitoring program
• 33 fraud analysis request | | `general` | • 11.1–11.3 authorization issues
• 12.1–12.7 processing errors
• 13.8 OCT not accepted
• 28 / 30 / 34 documentation requests | | `product_not_received` | • 13.1 merchandise / services not received
• 13.9 non-receipt of cash or load value | | `product_unacceptable` | • 13.3 not as described / defective
• 13.4 counterfeit
• 13.5 misrepresentation | | `subscription_canceled` | • 13.2 cancelled recurring |
| **xPay category** | **Mastercard codes** | | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `credit_not_processed` | • 4860 credit not processed | | `duplicate` | • 4834 duplicate / amount differs / multiple processing | | `fraudulent` | • 4837 no cardholder authorization
• 4849 questionable merchant activity
• 4870 chip liability shift
• 4871 chip liability shift – lost / stolen / NRI
• 6341 fraud investigation | | `general` | • 4808 authorization-related
• 4812 account number not on file
• 4831 amount differs
• 4859 addendum / no-show
• 6305 amount disagreement | | `product_not_received` | • 4855 goods or services not provided | | `product_unacceptable` | • 4853 not as described / defective / not provided | | `subscription_canceled` | • 4841 cancelled recurring or digital goods | | `unrecognized` | • 4863 cardholder does not recognize – potential fraud
• 6321 does not recognize transaction |
| **xPay category** | **Amex codes** | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `credit_not_processed` | • A01 charge exceeds authorization
• C02 credit not processed
• C04 goods returned / refused
• C05 goods cancelled
• C18 no-show / CARDeposit cancelled | | `duplicate` | • C14 paid by other means
• P08 duplicate charge
• 173 duplicate charge | | `fraudulent` | • F10 missing imprint
• F24 multiple ROCs
• F29 card not present
• F30 / F31 EMV liability shift
• FR2 / FR4 / FR5 / FR6 fraud programs
• 177 unauthorized
• 193 fraudulent charge | | `general` | • A02 no valid authorization
• A08 authorization expired
• P-series processing errors | | `product_not_received` | • C08 goods / services not received
• 004 product not received | | `product_unacceptable` | • C31 not as described
• C32 damaged / defective
• 024 goods damaged / defective | | `subscription_canceled` | • C28 cancelled recurring billing
• 021 goods / services cancelled | | `unrecognized` | • 127 / 176 unrecognized charge
• 691 requesting support |
# Reason codes Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/reason-codes What each dispute reason code means on a card, bank, ACH, or check transaction. Each dispute may include a machine-readable **reason code** that reflects why the customer or bank challenged the charge. When you see a code on a dispute in the dashboard, use the descriptions below to understand the claim and what evidence to gather. ## Card and chargeback reasons | **Code** | **Description** | | ----------------------- | -------------------------------------------------------------------------------------------------------------------------- | | `credit_not_processed` | The cardholder claims you have not yet refunded their return or cancellation. | | `customer_initiated` | The customer initiated a chargeback directly with their bank for an unspecified reason. | | `duplicate` | The customer was charged more than once for the same item or service. | | `fraudulent` | The customer claims they didn't authorize this payment — possibly due to card fraud or confusion over a legitimate charge. | | `general` | The customer disputed the charge, but the reason is unclear. You should contact them for more details. | | `product_not_received` | The customer says they didn't receive the product or service they paid for. | | `product_unacceptable` | The customer received the product but says it was damaged, defective, or not as described. | | `subscription_canceled` | The customer says you continued charging them after they canceled a subscription. | | `unrecognized` | The customer doesn't recognize the charge on their statement. This often overlaps with fraudulent disputes. | ## Bank, ACH, and check reasons | **Code** | **Description** | | --------------------------- | -------------------------------------------------------------------------------------------------------- | | `bank_cannot_process` | The bank was unable to process the transaction due to a temporary or permanent issue. | | `check_returned` | The check payment was returned, possibly due to insufficient funds or a closed account. | | `debit_not_authorized` | The debit was not authorized by the account holder, often indicating possible fraud or misunderstanding. | | `incorrect_account_details` | The transaction failed due to incorrect or invalid account information provided. | | `insufficient_funds` | The customer's account did not have enough funds to cover the transaction. | # Reducing disputes Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/reducing-disputes Best practices to prevent disputes before they happen. Every dispute withdraws your funds and can cost a fee even when you win, and losses hurt your performance score. Prevention beats defence: * **Always capture delivery confirmation** — tracking resolves most `product_not_received` disputes before they're filed. * **Make refunds easy and support responsive** — most disputes are a failed support interaction in disguise. * **Honor cancellations immediately** to avoid `subscription_canceled` disputes. * **Keep complete records** — invoices, communication, delivery proof, and agreed terms. You can't submit evidence you didn't keep. # Responding by reason Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/responding-by-reason How to fight or accept each dispute reason, and the evidence that makes a strong case. Each section below covers one dispute reason — **what the claim means**, **whether to fight or accept**, and the **primary evidence** that makes a strong case. Every counter-dispute is built from three layers of evidence: 1. **Mandatory documents** — required on every counter-dispute, whatever the reason: **customer communication** and the **payment invoice**. 2. **Reason-specific primary evidence** — the evidence tables in each section below. 3. **Secondary evidence** — the same [supporting set](/dashboard-operations/dispute-management/secondary-evidence) applies to every reason. ## Fraudulent, unrecognized & customer-initiated Applies to `fraudulent`, `unrecognized`, and `customer_initiated`. **The claim:** The customer says they didn't make or don't recognize the purchase. **Fight or accept?** Work out which of three situations you're in: * **Genuine fraud** — the card was used by an unrelated third party. Usually not winnable; accept and treat as a fraud signal. * **Authorized use** — the legitimate cardholder, or someone acting for them (an employee, family, or household member), actually made the payment. Winnable if you can show the link. * **Friendly fraud** — a real customer disowning their own purchase. Winnable; the tell is prior, undisputed purchases from the same customer. **Compelling evidence (primary):** What you send depends on the angle you're challenging on: * **Customer withdrew the dispute** — written confirmation, or acknowledgement that they recognize the charge and filed in error. * **You already refunded** — the refund reference, date, and amount. * **An authorized person made the payment** — evidence linking the buyer to the cardholder (e.g. a family/household member or authorized employee), or that the cardholder is in possession of and using what was bought. * **The purchase was legitimate (friendly fraud)** — a prior relationship: two or more earlier transactions from the same customer that weren't disputed, plus proof they received and used what they bought. For the friendly-fraud angle, Visa's compelling-evidence standard expects two prior transactions, each 120–365 days before the dispute date, with no active fraud report, sharing at least two of these — user ID, IP address, shipping address, device ID/fingerprint — with the disputed transaction (at least one being the IP address or device ID). **Primary evidence by challenge reason × product type:** | Challenge reason | Physical | Digital | Service | Booking | | ------------------------------------ | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------ | ------------------------------------------ | | Customer withdrew the dispute | Written confirmation they withdrew or will withdraw | Same | Same | Same | | Already refunded | Refund reference, date, and amount | Same | Same | Same | | Authorized person made it | Proof the buyer is linked to the cardholder; signature + ID at pickup; signed order form for phone/mail orders | Link to cardholder; access logs tied to them | Signature + ID; service link to cardholder | Signature + ID; booking tied to cardholder | | Legitimate purchase (friendly fraud) | Two prior matched orders — description, quantity, price; shipping details | + access/activity logs | + service date | + booking start & end dates | **No prior purchase history?** When the customer is new and you can't show a prior relationship, you're relying on showing the transaction had the hallmarks of a genuine purchase. In order of strength: 1. **AVS + CVV result — strong support, not a waiver.** A full AVS match (billing address matches the issuer's record) and a CVV match are compelling supporting evidence, but a match does **not** remove your liability — you may still have to argue the case and can still lose. For physical goods, shipping to the AVS-verified billing address is stronger still. A useful twist: if the CVC *was* presented but the issuer authorized the charge despite a failed check, or never verified it, that points liability back at the issuer. Store the CVV *result* (match / no-match), never the CVV value itself. 2. **IP, device & session data — supporting.** IP geolocation near the billing address, device geolocation at the time of the transaction, a recognized device ID / fingerprint, and session / login data build the picture that the genuine cardholder transacted. On their own they rarely win a true-fraud case, but they strengthen an AVS-backed response. If it's genuine third-party fraud, matching data shows the order looked legitimate but doesn't prove the cardholder authorized it, so these cases are difficult to win. Focus on preventing fraud at checkout rather than assembling evidence afterward. ## Credit not processed & subscription canceled Applies to `credit_not_processed` and `subscription_canceled`. **The claim:** The customer expected a refund/credit, or says you charged them after they cancelled. **Fight or accept?** Only fight if the refund isn't owed or you already issued it. If it's owed, refund instead. **Compelling evidence (primary):** * If already refunded: refund reference, date, and amount. * If cancelled: records showing the actual cancellation date versus the charge date. * If not eligible: your refund / cancellation policy and a note on why this case is excluded. | Challenge reason | Physical | Digital | Service | Booking | | ----------------------------- | ---------------------------------------------------------------- | ------- | ------- | ------- | | Customer withdrew the dispute | Written confirmation they withdrew or will withdraw | Same | Same | Same | | Already refunded | Refund reference, date, and amount | Same | Same | Same | | Cancelled before charge | Records showing the actual cancellation date vs. the charge date | Same | Same | Same | | Not eligible for refund | Refund / cancellation policy + why this case is excluded | Same | Same | Same | ## Duplicate Applies to `duplicate`. **The claim:** The customer was billed more than once for the same purchase. **Fight or accept?** Only fight if the charges are genuinely separate orders; otherwise refund the duplicate. **Compelling evidence (primary):** * Proof that each charge backs a distinct, valid order — description, quantity, price, and delivery/service detail for each. | Challenge reason | Physical | Digital | Service | Booking | | ----------------------------- | -------------------------------------------------------------------------------------- | ---------------------- | -------------- | --------------------------- | | Customer withdrew the dispute | Written confirmation they withdrew or will withdraw | Same | Same | Same | | Already refunded | Refund reference, date, and amount | Same | Same | Same | | Separate valid purchases | Proof each charge is a distinct order — description, quantity, price; shipping details | + access/activity logs | + service date | + booking start & end dates | ## Product not received Applies to `product_not_received`. **The claim:** The customer says what they paid for never arrived. **Fight or accept?** Fight if you can show delivery or availability. **Compelling evidence (primary):** * Physical: delivery confirmation (signed if possible), tracking, shipping address, ship date, stated delivery timeframe. * Digital: access/activity logs showing the customer's IP and access dates. * Service / booking: a service receipt with description, date, and signature, plus cancellation terms. | Challenge reason | Physical | Digital | Service | Booking | | ----------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | --------------- | | Customer withdrew the dispute | Written confirmation they withdrew or will withdraw | Same | Same | Same | | Already refunded | Refund reference, date, and amount | Same | Same | Same | | Delivered / will be delivered | Delivery confirmation (signed if possible); shipping docs with address and date; delivery-time terms | Access/activity logs with IP and access dates; cancellation terms for future-dated services | Service receipt (description, date, signature); cancellation terms | Same as service | ## Product unacceptable Applies to `product_unacceptable`. **The claim:** The customer received the item but says it's damaged, defective, or not as described. **Fight or accept?** Only fight if the claim is unfair; if genuinely defective, accept. **Compelling evidence (primary):** * Terms describing the product condition and refund policy. * An explanation of why the dispute is invalid against the terms the customer agreed to. * Where relevant, proof the item matched its description (photos, specs, listing). | Challenge reason | Physical | Digital | Service | Booking | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------- | ------- | ------- | | Customer withdrew the dispute | Written confirmation they withdrew or will withdraw | Same | Same | Same | | Already refunded | Refund reference, date, and amount | Same | Same | Same | | Not damaged / defective / as described | T\&Cs covering product condition and refund policy + explanation of why the dispute is invalid against agreed terms | Same | Same | Same | ## General Applies to `general`. **The claim:** Unspecified. **Fight or accept?** Contact the customer first to learn the real complaint, then gather evidence addressing it. **Compelling evidence (primary):** Any document that directly addresses the clarified concern. | Challenge reason | Physical | Digital | Service | Booking | | ----------------------------- | ------------------------------------------------------- | ------- | ------- | ------- | | Customer withdrew the dispute | Written confirmation they withdrew or will withdraw | Same | Same | Same | | Already refunded | Refund reference, date, and amount | Same | Same | Same | | Other | Any document that directly addresses the concern raised | Same | Same | Same | # Secondary evidence Source: https://docs.xpaycheckout.com/dashboard-operations/dispute-management/secondary-evidence Supporting evidence to attach alongside primary evidence for any dispute reason. This applies to **every** dispute reason. Attach it alongside the primary evidence for your specific reason to strengthen any card dispute. | Information | Physical product | Digital product | Offline service | Reservation / booking | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | Order details | • Description
• Quantity
• Price per item
• Shipping address
• Tracking number
• Carrier
• Ship date | • Description
• Quantity
• Price
• Access/activity logs
• Customer agreement to T\&Cs | • Description
• Quantity
• Price
• Service date
• Customer agreement to T\&Cs | • Description
• Quantity
• Price
• Booking start/end dates
• Customer agreement to T\&Cs | | Customer details | • Name
• Email
• IP address
• Billing address | Same | Same | Same | ## Bank, ACH & check disputes These use different reasons, and not all are won with evidence: * `debit_not_authorized` — treat like an unauthorized/fraud dispute; provide proof of authorization. * `incorrect_account_details`, `bank_cannot_process` — usually processing failures, not evidence disputes. Correct the details and re-attempt collection where possible. * `check_returned`, `insufficient_funds` — funding failures. Recover payment through another method rather than contesting. # Payouts Source: https://docs.xpaycheckout.com/dashboard-operations/payouts/payouts Information about payout cadence, limits, currency, statements, and FIRC ### Payout Schedule Payouts are initiated according to your schedule and typically arrive in your bank account within **24 to 48 working hours**. While xPay initiates the transfer on your scheduled payout day, your bank may require additional processing time. We send Payout delay emails at the beginning of the month to outline any delays due to holidays in India or US. ### Is there a minimum payout amount? * Default minimum payout threshold is \$500. If your balance is below your configured threshold, funds will accumulate until you meet it, then process on your next scheduled payout day. For any issues on this, you can get in touch with your account executive. * All payouts are made in **USD**. ### What payout schedules are available? To get more details on all available payout schedule methods or to make any modifications to the existing payout schedule, please reach out to our customer support. If no discussion has happened on the payout schedule, then the default payout will be initiated on Mondays and Thursdays. ### Why hasn't my payout been processed? **Common reasons:** * Balance below your configured minimum payout threshold * Not your scheduled payout day * Bank account verification pending * Weekend or bank holiday * Account under review Check your balance and payout status in **Balances**, or contact support for assistance. ### What happens if a payout fails? In your Xpay dashboard the balances status of your payout record will be marked as “Failed”. **To resolve:** 1. Check the failure reason in **Balances** 2. Contact Xpay support if needed Failed funds remain in your account and will be included in your next successful payout. ### How can I change my payout schedule? You need to contact the Xpay support. Support: [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com) ## Payout Dashboard ### How do I track my payout status? **View all payout activity in your XpayCheckout dashboard:** 1. Navigate to **Balances** in the left sidebar 2. View your payout history with details including: * **Payout ID:** Unique identifier for each payout * **Amount:** Total payout amount * **Initiated At:** Date and time payout was processed * **Payout Cutoff:** Cutoff date for included transactions * **Status:** Current payout status * **FIRC** certificate directly from the [dashboard](https://app.xpaycheckout.com/balances). * A detailed **Payout Statement** including ledger entries. Blurred 060e968b 5071 41fb A961 90da505ba46c Png(1) 1 *** # FIRC (Foreign Inward Remittance Certificate) > A Foreign Inward Remittance Certificate (FIRC) is an official document issued by banks in India as proof of inward remittance received in foreign currency. ## What is FIRC? * It serves as legal proof that funds have been received from abroad. * Commonly required for compliance, tax purposes, and record-keeping. ## Where can you use FIRC? * To claim tax exemptions or benefits in India. * As supporting documentation for audits or regulatory reporting. * To verify receipt of foreign payments for internal or external stakeholders. *** ## Troubleshooting & Support If your payout hasn’t arrived within the expected timeframe: * Confirm you met your configured minimum payout threshold set by your account executive. * Check your **FIRC** and payout statement for any errors. * Contact support if discrepancies are found. *** # Authentication Source: https://docs.xpaycheckout.com/developer-resources/authentication Authentication with xPay — Basic Authentication (RFC 7617) At xPay, we follow the Basic Auth RFC (RFC 7617) standard for authenticating requests made to our API. This ensures secure and straightforward access to the platform. ## How Basic Authentication Works ```javascript Node.js theme={null} const createHeaders = (username, password) => { const auth = `${username}:${password}`; const encodedAuth = Buffer.from(auth).toString("base64"); return { Authorization: `Basic ${encodedAuth}`, }; }; // Usage const headers = createHeaders("", ""); console.log(headers); // Never expose your API keys in your code or publicly. // For security purposes, always store your keys in your environment variables. // Exposing your keys can compromise your xPay account and the security of your transactions. // The axios library is a popular choice for making HTTP requests in Node.js and supports Basic Authentication natively. ``` ```java Java theme={null} import java.nio.charset.StandardCharsets; import java.util.Base64; import org.springframework.http.HttpHeaders; public class AuthUtils { public static HttpHeaders createHeaders(String username, String password) { String auth = username + ":" + password; byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.US_ASCII)); String authHeader = "Basic " + new String(encodedAuth); HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", authHeader); return headers; } // Usage public static void main(String[] args) { HttpHeaders headers = createHeaders("", ""); System.out.println(headers); } } // Never expose your API keys in your code or publicly. // For security purposes, always store your keys in your environment variables. // Exposing your keys can compromise your xPay account and the security of your transactions. // The Apache HttpClient is a good choice for making HTTP requests in Java and it supports Basic Authentication natively. ``` ```python Python theme={null} import base64 def create_headers(username, password): auth = f"{username}:{password}" encoded_auth = base64.b64encode(auth.encode('ascii')).decode('ascii') headers = { 'Authorization': f"Basic {encoded_auth}" } return headers # Usage headers = create_headers("", "") print(headers) # Never expose your API keys in your code or publicly. # For security purposes, always store your keys in your environment variables. # Exposing your keys can compromise your xPay account and the security of your transactions. # The requests library is the most commonly used for making HTTP requests in Python and supports Basic Authentication natively. ``` ```rust Rust theme={null} // First, make sure to include the `base64` crate in your `Cargo.toml` // [dependencies] // base64 = "0.13.0" use base64::encode; use std::collections::HashMap; fn create_headers(username: &str, password: &str) -> HashMap { let auth = format!("{}:{}", username, password); let encoded_auth = encode(auth); let mut headers = HashMap::new(); headers.insert("Authorization".to_string(), format!("Basic {}", encoded_auth)); headers } // Usage fn main() { let headers = create_headers("", ""); println!("{:?}", headers); } // Never expose your API keys in your code or publicly. // For security purposes, always store your keys in your environment variables. // Exposing your keys can compromise your xPay account and the security of your transactions. // The reqwest library is a popular choice for making HTTP requests in Rust and supports Basic Authentication natively. ``` In Basic HTTP Authentication, your request will contain an Authorization header with the following format: ```http theme={null} Authorization: Basic ``` Where `` represents your xPay authentication details — specifically, your **xPay Public Key** and **xPay Private Key**. These are combined and Base64 encoded for transmission: Go through [Get Your Keys](/developer-resources/getyourkeys) document to obtain your xPay authentication keys. Combine the **xPay Public Key** and **xPay Private Key** with a colon `:` separating them, forming this string:`:` Send the encoded credentials as part of your API request's **Authorization** header. For example, a typical Authorization header would look like: ```http theme={null} Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= ``` This Base64-encoded string represents the combination of username:password, in your case, the xPay Public Key and xPay Private Key. ## Using Postman for API Authentication To simulate API requests using Postman, follow these steps: Navigate to the **Authorization** tab in Postman. Under the Type dropdown, select **Basic Auth**. * In the **Username** field, enter your **xPay Public Key**. - In the **Password** field, enter your **xPay Private Key**. Postman will automatically handle the Base64 encoding and include the Authorization header in your requests. # Block Fingerprint by Intent Source: https://docs.xpaycheckout.com/developer-resources/endpoints/argus/block-fingerprint-by-intent POST /argus/block-fingerprint-by-intent Block the card fingerprint associated with a payment intent. A fingerprint can only be blocked if the intent is in one of: `SUCCESS`, `REFUNDED` Fingerprints are only available for card-based payment methods: `CARD`, `APPLE_PAY`, `GOOGLE_PAY`, and `CARD_INSTALLMENT`. The block may take up to 1 hour to take effect. ```json 204 theme={null} ``` ```json 400 theme={null} { "errorCode": "bad_request", "errorDescription": "Intent status does not allow block fingerprint" } ``` ```json 400 theme={null} { "errorCode": "bad_request", "errorDescription": "Payment method does not allow block fingerprint" } ``` ```json 400 theme={null} { "errorCode": "bad_request", "errorDescription": "Fingerprint already blocked" } ``` # Create Customer Source: https://docs.xpaycheckout.com/developer-resources/endpoints/customer/create-customer POST /customer/create Create a new customer in the xPay system # Get Customer Source: https://docs.xpaycheckout.com/developer-resources/endpoints/customer/get-customer GET /customer/{customerId} Get customer details by customer ID # List Payment Method Tokens Source: https://docs.xpaycheckout.com/developer-resources/endpoints/customer/get-pm-tokens-for-customer GET /customer/{customerId}/payment-method-tokens Retrieve a list of payment method tokens for a customer created within a specific time range, with support for filtering and pagination. This endpoint allows you to track and analyse all payment method tokens for a customer. It's useful for building dashboards, reconciling payment methods, or reviewing saved payment methods programmatically. # Payments Links Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payment-links/generate-link POST /link/merchant/generate-link This API can be used to generate payment links programmatically. Payments links are basically standalone webpages where your customer can make a one time payment. **These APIs generate payment links.** For proper integration, refer to [Create Intent](/developer-resources/endpoints/payments/create-intent). To learn more about the link, refer to the [Payment Links](/products/payment-links/payment-links) page in the Products section. # Subscription Link Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payment-links/subscription-link POST /subscription/link/merchant/generate-link This API can be used to generate subscription links programmatically. Subscription links are basically standalone webpages where your customer can make a subscription payment. **These APIs generate subscription links.** For proper integration, refer to [Create Subscription](/developer-resources/endpoints/subscriptions/create-subscription). To learn more about the link, refer to the [Payment Links](/products/payment-links/payment-links) page in the Products section. # Cancel Payment Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payments/cancel-payment POST /payments/cancel/{xIntentId} # Capture Payment Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payments/capture-payment POST /payments/capture-payment Captures a payment that was previously authorized by creating an intent with `manualCapture` set to `true`. # Charge Raw Card Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payments/charge-raw-card POST /payments/s2s/charge-raw-card Register the customer's card. Please redirect to the `nextActionRedirectURL`, where the customer can complete the payment with a single click. * Use this endpoint when you already gathered card details and consent within your PCI DSS compliant environment * You must obtain explicit approval from [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com) before using this API # Create Intent Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payments/create-intent POST /payments/create-intent This API is the first API to be called when the payment flow begins. Through this API, you inform xPay of the intent of the user to pay with all the requisite info about the user. # Get Intent Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payments/get-intent GET /payments/v2/get-intent/{xIntentId} You can use this API to get the status of the transaction that corresponds to a particular intent. This API also returns the masked card info of the payer (if it's a card transaction) and the transaction lifecycle, which includes multiple attempts, failures, and other checkpoints during a transaction. **Anti-Polling Warning**: Avoid polling this endpoint; use webhooks for real-time updates. See [Anti-Polling Policy](/developer-resources/rate-limits#quotas). # Get Refund Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payments/get-refund GET /payments/refund/{refundId} Get details of a single refund by refundId # Get Refunds of an Intent Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payments/get-refunds-for-intent GET /payments/refunds/{intentId} Retrieve a list of refunds for a specific payment intent # List Intents Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payments/list-intents GET /payments/intents Retrieve a list of payment intents created within a specific time range, with support for filtering and pagination. This endpoint allows you to track and analyse all payment attempts for your account. It's useful for building dashboards, reconciling payments, or reviewing recent transactions programmatically. # Refund Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payments/refund POST /payments/merchant/refund The Refund APIs allow merchants to process refunds for previously captured payments # Get Payout Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payouts/get-payout GET /balance/payouts/{payoutId} Get details of a single payout by payoutId # List Payouts Source: https://docs.xpaycheckout.com/developer-resources/endpoints/payouts/list-payouts GET /balance/payouts Retrieve a list of payouts created within a specific time range, with support for filtering and pagination. This endpoint allows you to track and analyse all payout transactions to your account. It's useful for building dashboards, reconciling payouts, or reviewing recent payout transactions programmatically. # Charge Tokenised PM Source: https://docs.xpaycheckout.com/developer-resources/endpoints/setup-method/charge-tokenised-pm POST /payments/charge-tokenised-pm Charge a payment using a tokenized payment method This feature is disabled by default. To turn it on for your account, please contact your account manager or [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com). # Create S2S Setup Method Source: https://docs.xpaycheckout.com/developer-resources/endpoints/setup-method/create-s2s-setup-method POST /setup-method/s2s/create Create a new setup method for storing payment methods server to server This endpoint is currently only available for card payments * Use this endpoint when you already gathered card details and consent within your PCI DSS compliant environment * You must obtain explicit approval from [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com) before using this API # Create Setup Method Source: https://docs.xpaycheckout.com/developer-resources/endpoints/setup-method/create-setup-method POST /setup-method/create Create a new setup method for storing payment methods This feature is disabled by default. To turn it on for your account, please contact your account manager or [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com). # Delete Tokenised Payment Method Source: https://docs.xpaycheckout.com/developer-resources/endpoints/setup-method/delete-tokenised-pm POST /payment-method-token/delete Delete a payment method token # Get Payment Method Token Source: https://docs.xpaycheckout.com/developer-resources/endpoints/setup-method/get-payment-method-token GET /payment-method-token/{paymentMethodTokenId} Get details of a payment method token This API allows you to retrieve the details of a payment method token, including its status and associated information. To get a list of payment method tokens for a customer, use the [/customers/payment-method-token](/developer-resources/endpoints/customer/get-pm-tokens-for-customer) endpoint. ## Status Values The payment method token can have one of the following statuses: * `LIVE`: The payment method token is active and can be used for transactions * `DELETED`: The payment method token has been deleted and cannot be used for transactions # Get Setup Method Source: https://docs.xpaycheckout.com/developer-resources/endpoints/setup-method/get-setup-method GET /setup-method/{setupMethodId} Get details of a setup method **Anti-Polling Warning**: Avoid polling this endpoint; use webhooks for real-time updates. See [Anti-Polling Policy](/developer-resources/rate-limits#quotas). # Cancel Subscription Source: https://docs.xpaycheckout.com/developer-resources/endpoints/subscriptions/cancel POST /subscription/merchant/cancel # Create Subscription Source: https://docs.xpaycheckout.com/developer-resources/endpoints/subscriptions/create-subscription POST /subscription/create # Edit Subscription Source: https://docs.xpaycheckout.com/developer-resources/endpoints/subscriptions/edit-subscription POST /subscription/edit All editable fields can only be modified if the subscription is in one of: `TRIALING`, `ACTIVE`, `UNPAID`, `PAUSED` # Get Subscription Source: https://docs.xpaycheckout.com/developer-resources/endpoints/subscriptions/get-subscription GET /subscription/get-subscription/{subscriptionId} **Anti-Polling Warning**: Avoid polling this endpoint; use webhooks for real-time updates. See [Anti-Polling Policy](/developer-resources/rate-limits#quotas). # Manual Retry Source: https://docs.xpaycheckout.com/developer-resources/endpoints/subscriptions/manual-retry POST /subscription/manual-retry Manually retry a failed payment for an existing subscription. This operation is only allowed when the subscription is in the `UNPAID` status and is subject to a 4-hour cooldown. # One Time Charge Source: https://docs.xpaycheckout.com/developer-resources/endpoints/subscriptions/one-time-charge POST /subscription/merchant/one-time-charge Charge a one-time amount against an existing subscription using its saved payment method. This feature is disabled by default. To turn it on for your account, please contact your account manager or [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com). # Pause Subscription Source: https://docs.xpaycheckout.com/developer-resources/endpoints/subscriptions/pause POST /subscription/merchant/pause # Unpause Subscription Source: https://docs.xpaycheckout.com/developer-resources/endpoints/subscriptions/unpause POST /subscription/merchant/unpause # Create a Webhook Configuration Source: https://docs.xpaycheckout.com/developer-resources/endpoints/webhooks/create-webhook POST /webhook Create a webhook configuration to receive realtime events for payments, intents, subscriptions, payouts, or setup methods. # Delete Webhook Configuration Source: https://docs.xpaycheckout.com/developer-resources/endpoints/webhooks/delete-webhook DELETE /webhook/{webhookConfigId} Delete an existing webhook configuration and stop delivery of future events to that endpoint. # Edit Webhook Configuration Source: https://docs.xpaycheckout.com/developer-resources/endpoints/webhooks/edit-webhook PUT /webhook/{webhookConfigId} Update an existing webhook configuration. Use this to rotate the event signer, change the destination endpoint, or adjust the subscribed event types. # Get Webhook Configuration Source: https://docs.xpaycheckout.com/developer-resources/endpoints/webhooks/get-webhook-by-id GET /webhook/{webhookConfigId} Retrieve a specific webhook configuration by its identifier. # List Webhook Configurations Source: https://docs.xpaycheckout.com/developer-resources/endpoints/webhooks/get-webhooks GET /webhook Retrieve the list of webhook configurations that are currently active for your account. # Errors Source: https://docs.xpaycheckout.com/developer-resources/errors Overview of xPay's HTTP response codes and error meanings. xPay uses standard HTTP response codes to indicate the success or failure of an API request. Codes in the `2xx` range signify success. Codes in the `4xx` range indicate client-side errors based on the information provided. Codes in the `5xx` range indicate errors related to xPay's servers. **Below is the list of HTTP status codes** | Code | Reason | Potential Root Cause | | ----- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `200` | Request is OK | The request was successfully received and processed. | | `400` | Bad Request | There’s something wrong about the request. Potentially incorrect parameters, insufficient parameters, or an issue with authentication. | | `401` | Unauthorized | You do not have access to the requested resource or your API keys are incorrect. | | `404` | Resource Not Found | You're likely hitting the wrong endpoint or the resource does not exist. | | `409` | Conflict | Multiple idempotent requests were hit concurrently. | | `429` | Too Many Requests | You have exceeded the rate limit. Please slow down your request rate. See [Rate Limits](/developer-resources/rate-limits) for more details. | | `500` | Internal Server Error | Likely a server-side issue on xPay's side. | Most errors in xPay will include an error code that can be used to handle the issue programmatically, along with a description that explains the reported problem. ## Attributes of the error object Example error object: ```json HTTP Status Code: 500 theme={null} { "errorCode": "internal_server_error", "errorDescription": "An unexpected error occurred on the server." } ``` A unique code representing the type of error that occurred. This code is used to identify specific issues and facilitate troubleshooting. A detailed message explaining the error represented by the error code. This description provides additional context to help understand the cause of the error. ## Error codes Below is a list of error codes that xPay may return in the `errorCode` field, along with information on how to resolve them. | Error Code | Description | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `internal_server_error` | Indicates that the server encountered an unexpected condition that prevented it from fulfilling the request. | | `bad_request` | The server cannot or will not process the request due to a client error (e.g., malformed request syntax). | | `resource_not_found` | The server can't find the requested resource, which could mean the URL is incorrect or the resource has been removed. | | `rate_limit_exceeded` | You have exceeded the rate limit. Please slow down your request rate and implement proper retry mechanisms. See [Rate Limits](/developer-resources/rate-limits) for more details. | | `unauthorized` | The request requires user authentication. If the request lacks valid authentication credentials, the server responds with this error. | | `conflict` | Returned when multiple idempotent requests are concurrently hit. | # Get Started Source: https://docs.xpaycheckout.com/developer-resources/getyourkeys To start integrating xPay into your platform, you need to set up your API keys and understand the base URL for making requests. This guide will walk you through both essential components. ## Get Your Keys API keys are essential for authenticating your requests and securely interacting with xPay's services. ### Steps to Get Your Keys: Navigate to [xPay Dashboard](https://app.xpaycheckout.com) and log in using your account credentials. Once logged in, navigate to the [Settings](https://app.xpaycheckout.com/settings) section, where you can find your **API Keys** in the **API Keys** tab. **Never expose your API keys in your code or publicly.**\ For security purposes, always store your keys in your **environment variables**. Exposing your keys can compromise your xPay account and the security of your transactions. ## Base URL All API requests to xPay should be made to the appropriate base URL depending on your environment: ### Production Environment ``` https://api.xpaycheckout.com ``` ### Sandbox Environment ``` https://api.test.xpaycheckout.com ``` ### Usage Example When making API calls, you'll combine the base URL with the specific endpoint. For example: ```bash theme={null} # Production curl -X POST https://api.xpaycheckout.com/v1/payments/create-intent \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" # Sandbox curl -X POST https://api.test.xpaycheckout.com/v1/payments/create-intent \ -H "Authorization: Bearer YOUR_SANDBOX_API_KEY" \ -H "Content-Type: application/json" ``` **Environment Selection**: Use the sandbox environment for testing and development. Switch to production only when you're ready to process real transactions. # Idempotent Requests Source: https://docs.xpaycheckout.com/developer-resources/idempotency Learn how to safely retry requests using idempotency keys xPay API supports idempotency for safely retrying requests without accidentally performing the same operation twice. When using an idempotency key, if a connection error occurs, you can safely repeat the request without risk of creating a second object or performing the update twice. ## How It Works To perform an idempotent request, provide an additional `Idempotency-Key` header to your request. xPay's idempotency works by saving the resulting status code and body of the first request made for any given idempotency key, regardless of whether it succeeds or fails. Subsequent requests with the same key return the same result. A merchant generates an idempotency key, which is a unique key that the server uses to recognize subsequent retries of the same request. ## Important considerations * **Key scope**: Idempotency keys cannot be shared across different idempotent APIs. * **Key expiration**: Idempotency keys expire after **24 hours** in our system. * A unique key for making the request idempotent. Must match pattern: `^[a-zA-Z0-9\-_:\.]+$` and not exceed 255 characters. * **Concurrent requests**: If a duplicate request is sent while the original request is still being processed, the API will return a `400 Bad Request` response indicating that the initial request is still in progress. * **Unsupported endpoints**: Only a few `POST` APIs support idempotency. Passing the `Idempotency-Key` header in unsupported APIs will result in a `400 Bad Request` error. * **Parameter matching**: The idempotency layer compares incoming parameters to those of the original request and errors if they're not the same to prevent accidental misuse. # Iframe Guidelines Source: https://docs.xpaycheckout.com/developer-resources/iframeGuidelines Quick guide to payment method support when embedding xPay Checkout in an iframe. ## Quick Reference | Payment Method | Iframe Support | Notes | | --------------------------- | ---------------------- | ---------------------------------------------- | | **Card payments** | ✅ **Fully supported** | Safe to use in iframe | | **Apple Pay** | ❌ **Not supported** | Requires top-level context | | **Google Pay** | ⚠️ **Limited support** | Needs `allow="payment"`, inconsistent behavior | | **BNPL (Klarna, Afterpay)** | ⚠️ **Poor UX** | Redirects break iframe flow | ## Key Limitations ### Apple Pay * **Cannot work in iframes** - Apple requires top-level browsing context * **Solution**: Use hosted checkout or open in new window ### Google Pay * **Requires** `allow="payment"` attribute on iframe * **Unreliable** - browser differences cause inconsistent behavior * **Solution**: Test thoroughly or use hosted checkout ### BNPL Providers * **Redirect-based flows** break iframe experience * **Poor UX** - redirects navigate parent window or open new tabs * **Solution**: Use hosted checkout for BNPL # Mobile App Integration Source: https://docs.xpaycheckout.com/developer-resources/mobileIntegration Learn how to embed your webpage inside a mobile WebView and properly handle deep links across different frameworks. If you're embedding our hosted webpage inside a mobile app using a **WebView**, you must ensure that **external deep links are properly handled** by opening them in their respective apps. This guide walks you through the setup for major mobile frameworks: *** ## Framework-Specific Setup ### Dependencies ```bash theme={null} flutter pub add webview_flutter url_launcher ``` ### Code Sample ```dart theme={null} if (checkoutUrl != null) { controller = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setNavigationDelegate( NavigationDelegate( onNavigationRequest: (NavigationRequest request) async { if (request.url.startsWith("myapp://payment-callback")) { _handleCallbackUrl(request.url); return NavigationDecision.prevent; } Uri url = Uri.parse(request.url); if (url.scheme != "http" && url.scheme != "https") { await launchUrl(url, mode: LaunchMode.externalApplication); return NavigationDecision.prevent; } return NavigationDecision.navigate; }, ), ) ..loadRequest(Uri.parse(checkoutUrl!)); } else { throw Exception("Failed to get checkout URL"); } ``` ### WebViewClient Code ```kotlin theme={null} webView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { return if (url != null && (url.startsWith("http") || url.startsWith("https"))) { false } else { try { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) context.startActivity(intent) true } catch (e: Exception) { true } } } } ``` ### WKWebView Delegate Example ```swift theme={null} func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if let url = navigationAction.request.url, !url.absoluteString.starts(with: "http") { if UIApplication.shared.canOpenURL(url) { UIApplication.shared.open(url, options: [:], completionHandler: nil) decisionHandler(.cancel) return } } decisionHandler(.allow) } ``` ### Install Dependencies ```bash theme={null} npm install react-native-webview ``` ### WebView Setup ```tsx theme={null} import { Linking } from 'react-native'; import { WebView } from 'react-native-webview'; { const url = request.url; if (!url.startsWith('http')) { Linking.openURL(url).catch(err => console.warn('Failed to open URL:', err)); return false; } return true; }} /> ``` *** ## WebView Keyboard Handling When embedding the checkout page inside a mobile WebView, the WebView often shrinks when the keyboard opens, which results in a poor user experience. Input fields or the Pay button may get hidden, forcing the user to scroll in awkward ways. To ensure a smooth experience, configure the WebView so that the keyboard pans over the WebView instead of shrinking it. This allows the WebView to remain in place, keeps input fields properly focused, and ensures that critical actions like completing payment stay visible. For Example in **Flutter**, you can configure the Scaffold to prevent the WebView from shrinking. ```dart theme={null} Scaffold( resizeToAvoidBottomInset: false, // Prevents WebView from shrinking body: WebViewWidget(controller: controller), ) ``` *** ## Google Pay Integration ### Chrome Custom Tab (CCT) Integration Chrome Custom Tabs provide a seamless way to display web content within your Android app while maintaining the native look and feel. **For Google Pay integration on Android, we strongly recommend using CCT instead of WebView** for better performance, security, and native user experience. #### Dependencies ```bash theme={null} flutter pub add flutter_inappwebview url_launcher ``` #### Code Sample ```dart theme={null} import 'package:url_launcher/url_launcher.dart'; // Launch payment URL in Chrome Custom Tab (Android) or Safari (iOS) Future launchPaymentUrl(String paymentUrl) async { final Uri uri = Uri.parse(paymentUrl); if (await canLaunchUrl(uri)) { await launchUrl( uri, mode: LaunchMode.externalApplication, webViewConfiguration: const WebViewConfiguration( enableJavaScript: true, enableDomStorage: true, ), ); } else { throw Exception('Could not launch payment URL'); } } ``` #### Dependencies ```kotlin theme={null} // build.gradle implementation 'androidx.browser:browser:1.7.0' ``` #### Code Sample ```kotlin theme={null} import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabColorSchemeParams import androidx.core.content.ContextCompat val customTabsIntent = CustomTabsIntent.Builder() .setColorSchemeParams( CustomTabColorSchemeParams.Builder() .setToolbarColor(ContextCompat.getColor(this, R.color.primary)) .build() ) .setShowTitle(true) .setStartAnimations(this, R.anim.slide_in_right, R.anim.slide_out_left) .setExitAnimations(this, R.anim.slide_in_left, R.anim.slide_out_right) .build() // Launch the payment URL in CCT customTabsIntent.launchUrl(this, Uri.parse(paymentUrl)) ``` #### Code Sample ```swift theme={null} import SafariServices func launchPaymentURL(_ urlString: String) { guard let url = URL(string: urlString) else { return } let safariVC = SFSafariViewController(url: url) safariVC.preferredBarTintColor = UIColor.systemBlue safariVC.preferredControlTintColor = UIColor.white present(safariVC, animated: true) } ``` #### Install Dependencies ```bash theme={null} npm install react-native-inappbrowser-reborn ``` #### Code Sample ```tsx theme={null} import { InAppBrowser } from 'react-native-inappbrowser-reborn'; const launchPaymentURL = async (url: string) => { try { const result = await InAppBrowser.open(url, { // iOS options dismissButtonStyle: 'cancel', preferredBarTintColor: '#453AA4', preferredControlTintColor: 'white', readerMode: false, animated: true, modalPresentationStyle: 'fullScreen', modalTransitionStyle: 'coverVertical', modalEnabled: true, enableBarCollapsing: false, // Android options showTitle: true, toolbarColor: '#453AA4', secondaryToolbarColor: 'black', navigationBarColor: 'black', navigationBarDividerColor: 'white', enableUrlBarHiding: true, enableDefaultShare: true, forceCloseOnRedirection: false, animations: { startEnter: 'slide_in_right', startExit: 'slide_out_left', endEnter: 'slide_in_left', endExit: 'slide_out_right', }, }); } catch (error) { console.error('Error launching payment URL:', error); } }; ``` ### WebView Integration with Google Pay **Note**: While CCT is the recommended approach for Google Pay on Android, if you must use WebView instead, refer to the [Google Pay Android WebView guide](https://developers.google.com/pay/api/android/guides/recipes/using-android-webview) for complete integration details. *** ## Android & iOS Requirements ### Android If your app wants to check if other apps are installed or can handle specific intents (like deep links or custom schemes) before launching them, you need to declare those intents inside the `` tag in your app's `AndroidManifest.xml`. This is mandatory starting Android 11 (API 30) for privacy reasons. Without this, calls like `PackageManager.queryIntentActivities()` or launching those intents may not work as expected. ### iOS If your app wants to check whether other apps are installed that support certain custom URL schemes before opening them (using `canOpenURL`), you must declare those schemes inside the `LSApplicationQueriesSchemes` array in your `Info.plist`. Without this, `canOpenURL` will always return false for those schemes (except for some system schemes). This is required since iOS 9 for privacy reasons. ### Summary | Platform | Requirement | | -------- | ------------------------------------------------------------------------ | | Android | Declare intent filters inside `` tag in `AndroidManifest.xml` | | iOS | Declare URL schemes inside `LSApplicationQueriesSchemes` in `Info.plist` | ### Example #### Android (AndroidManifest.xml) ```xml theme={null} ``` #### iOS (Info.plist) ```xml theme={null} LSApplicationQueriesSchemes cashme ``` *** If deep links are not handled as described, your app may not open apps like Cash App or klarna from within the WebView. # Pagination Source: https://docs.xpaycheckout.com/developer-resources/pagination xPay API utilizes [cursor](http://en.wikipedia.org/wiki/Cursor_\(databases\)) based pagination to efficiently handle large datasets. All list API methods share a common structure and accept pagination parameters to facilitate navigation through results. ## Understanding Cursor-Based Pagination Cursor based pagination utilizes a special token (called an `offset`) that functions as a bookmark, instructing the API precisely where to resume fetching data from. This approach is efficient for large datasets because it eliminates the necessity for the API to count total results. ## Implementation Steps 1. **Initial request**: Omit `offset` parameter 2. **Continue**: For each subsequent request, supply the exact `offset` value received in the previous response's `metadata.offset` field. Do not alter, generate, or reuse old offsets. 3. **Complete**: Terminate when `metadata.offset` is absent or null **Modifying query parameters**: Changing any query parameters (such as filters or sorting) invalidates current offsets, restart pagination from the beginning if you change them. **Too many requests**: Excessive paginated requests within a short period may result in [rate limiting](/developer-resources/rate-limits). ## Parameters Specifies the number of objects to return, ranging between 1 and 100. Default varies by endpoint. An opaque string that defines your position in the list. **Critical**: Utilize the exact `offset` value from the previous response's `metadata.offset` field. Do not modify, decode, or generate your own offset values. ## Response Format All paginated endpoints return responses in this format: Array of response elements containing the actual data objects Metadata object containing pagination information Cursor for the next page. When absent or null, you've reached the conclusion # Rate Limits Source: https://docs.xpaycheckout.com/developer-resources/rate-limits Learn about API rate limits and how to work with them. xPay employs sophisticated [rate limiting](https://en.wikipedia.org/wiki/Rate_limiting) mechanisms to ensure optimal API performance and equitable resource distribution across all merchants. Our rate limiting system orchestrates request throughput to maintain peak performance and prevent system overload, encompassing all API endpoints within your merchant account. When you exceed these thresholds, you'll encounter error responses with status code `429`. Each API request consumes quota from your allocated allowance. ## Quotas Our throttling system enforces the following request quotas per minute: * **Live mode**: 10 requests per second * **Sandbox**: 10 requests per second These quotas encompass all API endpoints within your merchant account. Every API call consumes quota from your allocated allowance. **Avoid polling** - Polling APIs repeatedly to check for status changes is strictly discouraged and will rapidly exhaust your rate limits. **Use Webhooks Instead**: For real-time status updates, utilize webhooks instead of polling. Webhooks provide instantaneous notifications when status changes occur, eliminating the necessity for repeated API calls. For webhook implementation details, see [Webhooks](/developer-resources/webhooks/introduction). **Anticipate traffic surges**: Proactively plan for high-volume events by contacting xPay support at [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com) to discuss your expected traffic patterns and ensure your integration can handle the load. ## Response When you exceed the throttling threshold, requests return a `429 Too Many Requests` status code: ```json HTTP Status Code: 429 theme={null} { "errorCode": "rate_limit_exceeded", "errorDescription": "Too many requests. Please slow down your request rate." } ``` # Payment Test Simulation Source: https://docs.xpaycheckout.com/developer-resources/sandbox/payment-test-simulation Test credentials and simulation scenarios for payment methods in the xPay sandbox environment Use the credentials and test card numbers below to simulate payments in the sandbox environment. These only work in sandbox — use the [Sandbox Dashboard](https://app.test.xpaycheckout.com/) and sandbox API keys. See the [Sandbox Environment](/developer-resources/sandbox/sandbox) guide for setup details. ## Card Use these test cards to simulate successful and failed card payments in sandbox checkout. ### Success | Card | Card Number | Expiry | CSC | | ---------- | --------------------- | --------------- | ---------------- | | Mastercard | `5555 5555 5555 4444` | Any future date | Any 3-digit code | ### Failure | Card | Card Number | Expiry | CSC | | ---- | --------------------- | --------------- | ---------------- | | Visa | `4000 0000 0000 0002` | Any future date | Any 3-digit code | *** ## Card Installments Use this test card to simulate a successful Card Installments payment in sandbox. | Card | Card Number | Expiry | CSC | | ---------- | --------------------- | --------------- | ---------------- | | Mastercard | `5444 4444 4444 4445` | Any future date | Any 3-digit code | *** ## Klarna Use these credentials when prompted during Klarna checkout in sandbox. | Label | Value | Details | | ----------------------- | ---------------- | ---------------------------------------------------------------------- | | Phone Number | `(888) 254-4887` | Enter this phone number when prompted for Klarna login | | OTP (One-Time Password) | `123456` | Use any 6-digit number as OTP when prompted (e.g., `123456`, `000000`) | For more on Klarna integration and requirements, see [Klarna FAQs](/faqs/klarna-overview). *** ## PayPal Use these credentials to test PayPal payments in sandbox. | Label | Value | Details | | ----------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------- | | Email | `test@xpaycheckout.com` | Login email for PayPal sandbox account | | Password | `xpay@2468` | Password for PayPal sandbox account | | Test Cards Portal | [PayPal sandbox card testing](https://developer.paypal.com/tools/sandbox/card-testing/) | PayPal developer portal for managing test cards | These are sandbox-only credentials. Never use them in production or share them outside your testing workflow. # Sandbox Environment Source: https://docs.xpaycheckout.com/developer-resources/sandbox/sandbox Test your xPay integration in a safe sandbox environment with cloned account data ## What is the Sandbox Environment? The sandbox is a complete clone of your xPay account that operates in an isolated testing environment. It provides: * **Identical Features**: Most production features are available for testing * **Safe Testing**: No real money is processed, no real customers are affected * **Full Functionality**: Test payments, subscriptions, refunds, and most API endpoints ## Sandbox API Endpoint Sandbox Endpoint: [https://api.test.xpaycheckout.com](https://api.test.xpaycheckout.com) ## Sandbox Dashboard Access Once you have sandbox access, you can access your sandbox environment at: **Sandbox Dashboard**: [https://app.test.xpaycheckout.com/](https://app.test.xpaycheckout.com/) ## Getting Sandbox Access Reach out to our support team to request sandbox access for your account. You can contact us through the dashboard or via email. Our team will verify your account and prepare your sandbox environment with a complete clone of your production settings. You'll receive: * **Sandbox Email**: Login email for the sandbox dashboard * **Sandbox Password**: Secure password for sandbox access ## Sandbox API Keys Your sandbox environment comes with dedicated API keys that are separate from your production keys. You can generate your sandbox API keys directly from the sandbox dashboard. For detailed instructions on how to obtain your API keys, see our [Get Your Keys](/developer-resources/getyourkeys) guide. **Never use sandbox keys in production or production keys in sandbox.**\ Always ensure you're using the correct set of keys for the environment you're working in. ## Switching Between Environments Use sandbox environment with sandbox API keys for all development and testing. Switch to production environment with live API keys only when ready for real transactions. Use environment variables to manage different API keys: ```bash theme={null} # Sandbox XPAY_PUBLIC_KEY=your_sandbox_public_key XPAY_PRIVATE_KEY=your_sandbox_private_key XPAY_BASE_URL=https://api.test.xpaycheckout.com # Production XPAY_PUBLIC_KEY=your_live_public_key XPAY_PRIVATE_KEY=your_live_private_key XPAY_BASE_URL=https://api.xpaycheckout.com ``` Sandbox data may be periodically reset to ensure a clean testing environment. Any test data you create may be cleared during these resets. For test card numbers and payment method credentials, see [Payment Test Simulation](/developer-resources/sandbox/payment-test-simulation). **Remember**: The sandbox environment is for testing only. Never process real payments or use real customer data in the sandbox environment. # Webhook Events Directory Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events-list Quick access list for every webhook event emitted by xPay. ### Intent events * [`intent.created`](/developer-resources/webhooks/events/intentEvents/created) * [`intent.checkout_opened`](/developer-resources/webhooks/events/intentEvents/checkout_opened) * [`intent.authorized`](/developer-resources/webhooks/events/intentEvents/authorized) * [`intent.success`](/developer-resources/webhooks/events/intentEvents/success) * [`intent.failed`](/developer-resources/webhooks/events/intentEvents/failed) * [`intent.refunded`](/developer-resources/webhooks/events/intentEvents/refunded) * [`intent.disputed`](/developer-resources/webhooks/events/intentEvents/disputed) * [`intent.dispute_under_review`](/developer-resources/webhooks/events/intentEvents/dispute_under_review) * [`intent.dispute_won`](/developer-resources/webhooks/events/intentEvents/disputedWon) * [`intent.dispute_lost`](/developer-resources/webhooks/events/intentEvents/dispute_lost) * [`intent.early_fraud_warning`](/developer-resources/webhooks/events/intentEvents/early_fraud_warning) ### Subscription events * [`subscription.created`](/developer-resources/webhooks/events/subsEvents/created) * [`subscription.checkout_opened`](/developer-resources/webhooks/events/subsEvents/checkout_opened) * [`subscription.trialing`](/developer-resources/webhooks/events/subsEvents/trialing) * [`subscription.active`](/developer-resources/webhooks/events/subsEvents/active) * [`subscription.paused`](/developer-resources/webhooks/events/subsEvents/paused) * [`subscription.unpaused`](/developer-resources/webhooks/events/subsEvents/unpaused) * [`subscription.cycle_charged`](/developer-resources/webhooks/events/subsEvents/cycle_charged) * [`subscription.unpaid`](/developer-resources/webhooks/events/subsEvents/unpaid) * [`subscription.payment_method_updated`](/developer-resources/webhooks/events/subsEvents/payment_method_updated) * [`subscription.ended`](/developer-resources/webhooks/events/subsEvents/ended) * [`subscription.cancelled`](/developer-resources/webhooks/events/subsEvents/cancelled) ### Setup method events * [`setup_method.created`](/developer-resources/webhooks/events/setupMethodEvents/created) * [`setup_method.checkout_opened`](/developer-resources/webhooks/events/setupMethodEvents/checkout_opened) * [`setup_method.success`](/developer-resources/webhooks/events/setupMethodEvents/success) * [`setup_method.failed`](/developer-resources/webhooks/events/setupMethodEvents/failed) * [`payment_method_token.created`](/developer-resources/webhooks/events/setupMethodEvents/payment_method_token_created) * [`payment_method_token.deleted`](/developer-resources/webhooks/events/setupMethodEvents/payment_method_token_deleted) ### Payout events * [`payout.initiated`](/developer-resources/webhooks/events/payoutEvents/initiated) * [`payout.success`](/developer-resources/webhooks/events/payoutEvents/success) ### Virtual bank account events * [`virtual_bank_account.transaction`](/developer-resources/webhooks/events/vbaEvents/transaction) # Authorized Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/authorized This event is triggered when a payment intent is successfully authorized and is ready to be captured. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.authorized", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "status": "AUTHORIZED", "amount": 5000, "currency": "USD", "paymentMethod": "CARD", "customerDetails": { "name": "John Doe", "email": "john@doe.com", "contactNumber": "+919123456789", "customerAddress": { "addressLine1": "123 Main St", "addressLine2": "Apt 1", "city": "New York", "state": "NY", "country": "US", "postalCode": "10001" } }, "paymentMetadata": { "paymentMethod": "CARD", "cardMetadata": { "brand": "visa", "country": "US", "lastFourDigit": "4242", "expiryMonth": 4, "expiryYear": 2044, "cardType": "CREDIT" } }, "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this event. The type of event. For this event, the value is `intent.authorized`. The time at which the event was generated, expressed as milliseconds since the Unix epoch. The unique identifier of the authorized payment intent. Your identifier for the order. The current status of the payment intent. For this event, the value is `AUTHORIZED`. The authorized amount in the smallest unit of the currency. For example, `5000` represents 50.00 USD. The currency of the authorized amount. The payment method used for the transaction. See [supported payment methods](/get-started/payment-methods-supported#payment-method-enums). Information about the customer, including their name, email address, contact number, and billing address. Metadata for the payment method used to authorize the transaction. For card payments, this can include the card brand, issuing country, last four digits, expiry date, and card type. The custom key-value pairs provided when the payment intent was created. # Checkout Opened Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/checkout_opened This event is triggered when a payment intent's checkout page is opened by a customer. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.checkout_opened", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment intent's checkout page has been opened. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent whose checkout page was opened. Your identifier of the order. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Created Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/created This event is triggered when a new payment intent is successfully created. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.created", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "status": "CREATED", "amount": 5000, "currency": "USD", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment intent has been created. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent. This ID ties the event back to a particular transaction or payment process that triggered the event. Your identifier of the order. Represents the current status of the payment intent. For this event, the status will be `CREATED`. The amount involved in the transaction, typically expressed in the smallest unit of the currency. Here, 5000 represents 50.00 USD (because USD typically uses two decimal places). The currency used for the transaction. In this case, it is United States Dollars (USD). A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Dispute Lost Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/dispute_lost This event indicates that a payment intent dispute has been lost, meaning the dispute was resolved in favor of the customer and the funds have been returned to them. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.dispute_lost", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "disputeId": "dp_fooBOwYsaK50AEfK", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment intent dispute has been lost in favor of the customer. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent that was disputed. This ID ties the event back to the transaction or payment process that was disputed. Your identifier of the order. A unique identifier for the specific dispute that triggered this event. This ID ties the event back to the dispute record so you can correlate it directly. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Dispute Under Review Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/dispute_under_review This event indicates that a payment intent dispute is currently under review, meaning the dispute is being investigated and no final decision has been made yet. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.dispute_under_review", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "disputeId": "dp_fooBOwYsaK50AEfK", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment intent dispute is currently under review and being investigated. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent that is under dispute review. This ID ties the event back to the transaction or payment process that is being disputed. Your identifier of the order. A unique identifier for the specific dispute that triggered this event. This ID ties the event back to the dispute record so you can correlate it directly. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Disputed Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/disputed This event indicates that a payment intent has been disputed, often due to a chargeback or customer claim. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.disputed", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "disputeId": "dp_fooBOwYsaK50AEfK", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment intent has been successfully disputed. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent that was refunded. This ID ties the event back to the transaction or payment process that triggered the refund. Your identifier of the order. A unique identifier for the specific dispute that triggered this event. This ID ties the event back to the dispute record so you can correlate it directly. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Dispute Won Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/disputedWon This event indicates that a payment intent dispute has been resolved in favor of the merchant, allowing them to retain the funds. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.dispute_won", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "disputeId": "dp_fooBOwYsaK50AEfK", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment intent dispute has been won in favor of the merchant. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent that was refunded. This ID ties the event back to the transaction or payment process that triggered the refund. Your identifier of the order. A unique identifier for the specific dispute that triggered this event. This ID ties the event back to the dispute record so you can correlate it directly. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Early Fraud Warning Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/early_fraud_warning This event indicates a payment intent flagged as potentially fraudulent, ahead of any formal dispute. Acting on it early can help you avoid a chargeback. An early fraud warning is a signal raised that a charge is likely fraudulent. It is delivered *before* a dispute is opened, giving you an opportunity to proactively refund the payment, cancel any pending fulfilment, or reach out to the customer to reduce the risk of an incoming chargeback. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.early_fraud_warning", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "fraudType": "made_with_stolen_card" } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that an early fraud warning has been raised against a payment intent. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent that the warning was raised against. This ID ties the event back to the transaction so you can locate and act on the charge. The category of fraud reported by the card network or issuing bank. One of: | Value | Description | | ----------------------------- | --------------------------- | | `card_never_received` | Card Never Received | | `fraudulent_card_application` | Fraudulent Card Application | | `made_with_counterfeit_card` | Made With Counterfeit Card | | `made_with_lost_card` | Made With Lost Card | | `made_with_stolen_card` | Made With Stolen Card | | `unauthorized_use_of_card` | Unauthorized Use of Card | | `misc` | Miscellaneous | # Failed Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/failed This event is triggered when the payment process for a given intent fails due to an error or insufficient funds. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.failed", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "status": "FAILED", "amount": 5000, "currency": "USD", "errorCode": "insufficient_funds", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment intent is failed. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent. This ID ties the event back to a particular transaction or payment process that triggered the event. Your identifier of the order. Represents the current status of the payment intent. For this event, the status will be `FAILED`. The amount involved in the transaction, typically expressed in the smallest unit of the currency. Here, 5000 represents 50.00 USD (because USD typically uses two decimal places). The currency used for the transaction. In this case, it is United States Dollars (USD). A specific code indicating the reason for the payment failure. This helps identify whether the failure was due to user error or processing error. For a complete list of error codes and their meanings, see our [Error Codes](/products/one-time-payments/error-codes) documentation. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Refunded Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/refunded This event indicates that a payment intent has been successfully refunded. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.refunded", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "refundId": "rf_fooBOwYsaK50AEfi", "refundReferenceId": "re123", "status": "REFUNDED", "amount": 10000, "currency": "USD", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment intent has been successfully refunded. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent that was refunded. This ID ties the event back to the transaction or payment process that triggered the refund. Your identifier of the order. A unique identifier for the specific refund that triggered this event. This ID ties the event back to the refund record so you can correlate it directly. Represents the current status of the payment intent. For this event, the status will be `REFUNDED`. Your identifier for the refund. The refunded amount for the transaction, typically expressed in the smallest unit of the currency. Here, 10000 represents 100.00 USD (because USD typically uses two decimal places). The currency used for the refunded transaction. In this case, it is United States Dollars (USD). A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Success Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/intentEvents/success This event indicates that the payment intent has been successfully processed and the payment is complete. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "intent.success", "eventTime": 1729608043615, "intentId": "in_fooBOwYsaK50AEfK", "receiptId": "recp_123311", "status": "SUCCESS", "amount": 100, "currency": "USD", "paymentMethod": "CARD", "customerDetails": { "name": "John Doe", "email": "john@doe.com", "contactNumber": "+919123456789", "customerAddress": { "addressLine1": "123 Main St", "addressLine2": "Apt 1", "city": "New York", "state": "NY", "country": "US", "postalCode": "10001" } }, "paymentMetadata": { "paymentMethod": "CARD", "cardMetadata": { "brand": "visa", "country": "US", "lastFourDigit": "4242", "expiryMonth": 4, "expiryYear": 2044, "cardType": "CREDIT" } }, "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment intent is successful. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment intent. This ID ties the event back to a particular transaction or payment process that triggered the event. Your identifier of the order. Represents the current status of the payment intent. For this event, the status will be `SUCCESS`. The amount involved in the transaction, typically expressed in the smallest unit of the currency. Here, 100 represents 1.00 USD (because USD typically uses two decimal places). The currency used for the transaction. In this case, it is United States Dollars (USD). The payment method used for the transaction. [supported payment methods](/get-started/payment-methods-supported#payment-method-enums) Contains information about the customer who made the payment: * **name**: The full name of the customer * **email**: The email address of the customer * **contactNumber**: The contact phone number of the customer, in [E.164 format](https://en.wikipedia.org/wiki/E.164) * **customerAddress**: The customer's address, containing: * **addressLine1**: Line 1 of the customer's address * **addressLine2**: Line 2 of the customer's address * **city**: City of the customer's address * **state**: State of the customer's address * **country**: Two-letter country code ([ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)) * **postalCode**: Postal code Contains metadata about the payment used for the transaction: * **paymentMethod**: The payment method used for the transaction. See [supported payment methods](/get-started/payment-methods-supported#payment-method-enums). * **cardMetadata**: Card details (present only for card payments), containing: * **brand**: The brand of the card (e.g., `amex`, `diners`, `discover`, `jcb`, `mastercard`, `unionpay`, `visa`, `rupay`), among others. * **country**: The issuing country of the card. * **lastFourDigit**: The last four digits of the card number. * **expiryMonth**: The expiration month of the card. * **expiryYear**: The expiration year of the card. * **cardType**: The type of card funding (`CREDIT`, `DEBIT`, `PREPAID`, or `UNKNOWN`). * **cardInstallmentMetadata**: Card installment (EMI) details (present only for `CARD_INSTALLMENT` payments), containing: * **cardInstallmentTenure**: The installment tenure in months (`three`, `six`, `nine`, or `twelve`). A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Payout Initiated Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/payoutEvents/initiated This event is triggered when a payout is successfully initiated. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "payout.initiated", "eventTime": 1729608043615, "payoutId": "po_fooBOwYsaK50AEfK", "amount": 50000, "untilTime": 1729608043615, "initiatedAt": 1729608043615 } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payout has been initiated. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payout. This ID ties the event back to a particular payout process that triggered the event. The total amount of the payout, typically expressed in the smallest unit of the currency. Here, 50000 represents 500.00 USD (because USD typically uses two decimal places). The timestamp representing the cutoff time for this payout period, in milliseconds since the Unix epoch. This indicates the end of the period for which this payout covers. The timestamp when the payout was initiated, in milliseconds since the Unix epoch. This represents the exact moment when the payout process began. # Payout Success Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/payoutEvents/success This event is triggered when a payout is successfully completed. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "payout.success", "eventTime": 1729608043615, "payoutId": "po_fooBOwYsaK50AEfK" } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payout has been successfully completed. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payout. This ID ties the event back to a particular payout process that has been successfully completed. # Setup Method Checkout Opened Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/setupMethodEvents/checkout_opened This event is triggered when a setup method's checkout page is opened by a customer. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "setup_method.checkout_opened", "eventTime": 1729608043615, "setupMethodId": "sm_sK8d3Jq1tZxPjYVhRQW2rf", "receiptId": "order123", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a setup method's checkout page has been opened. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific setup method whose checkout page was opened. Your identifier for the order. Present only when provided during setup method creation. A collection of key-value pairs that were provided when the setup method was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. # Setup Method Created Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/setupMethodEvents/created This event is triggered when a new setup method is created. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "setup_method.created", "eventTime": 1729608043615, "setupMethodId": "sm_sK8d3Jq1tZxPjYVhRQW2rf", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a new setup method has been created. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific setup method that was created. Your identifier for the order. Present only when provided during setup method creation. A collection of key-value pairs that were provided when the setup method was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. # Setup Method Failed Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/setupMethodEvents/failed This event is triggered when a setup method fails. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "setup_method.failed", "eventTime": 1729608043615, "setupMethodId": "sm_sK8d3Jq1tZxPjYVhRQW2rf", "errorCode": "setup_method_authorisation_failed", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a setup method has failed. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific setup method that failed. Your identifier for the order. Present only when provided during setup method creation. A specific code indicating the reason for the setup method failure. This helps identify whether the failure was due to user error or processing error. For a complete list of error codes and their meanings, see our [Error Codes](/products/one-time-payments/error-codes) documentation. A collection of key-value pairs that were provided when the setup method was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. # Payment Method Token Created Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/setupMethodEvents/payment_method_token_created This event is triggered when a new payment method token is created. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "payment_method_token.created", "eventTime": 1729608043615, "pmId": "pmt_ftoeKIYGC3f43frT", "customerId": "cus_Tfd3Jq1tZxPjYVhRQW2r3", "paymentMethod": "CARD", "currencies": ["USD", "EUR"], "metadata": { "orderId": "12345", "customerNote": "Setup for recurring payments" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a new payment method token has been created. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment method token that was created. The unique identifier of the customer associated with this payment method token. The type of payment method that was tokenized. The currencies supported by the payment method token. A collection of key-value pairs that were provided as `metadata` when the token was first created. These `metadata` values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. # Payment Method Token Deleted Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/setupMethodEvents/payment_method_token_deleted This event is triggered when a payment method token is deleted. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "payment_method_token.deleted", "eventTime": 1729608043615, "pmId": "pmt_ftoeKIYGC3f43frT", "customerId": "cus_Tfd3Jq1tZxPjYVhRQW2r3", "paymentMethod": "CARD", "metadata": { "orderId": "12345", "customerNote": "Setup for recurring payments" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a payment method token has been deleted. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific payment method token that was deleted. The unique identifier of the customer associated with this payment method token. The type of payment method that was deleted. A collection of key-value pairs that were provided as `metadata` when the token was first created. These `metadata` values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. # Setup Method Success Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/setupMethodEvents/success This event is triggered when a setup method is successfully completed. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "setup_method.success", "eventTime": 1729608043615, "setupMethodId": "sm_sK8d3Jq1tZxPjYVhRQW2rf", "pmId": "pmt_ftoeKIYGC3f43frT", "intentId": "in_ftoeKIYGC3f43frX", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a setup method has been successfully completed. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific setup method that was completed successfully. The unique identifier of the payment method that was successfully set up. The unique identifier of the payment intent created while setting up the payment method token. Present only when `amount` is passed during setup creation. Your identifier for the order. Present only when provided during setup method creation. A collection of key-value pairs that were provided when the setup method was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. # Active Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/active This event is triggered when a subscription transitions to the active state, indicating it is ready for billing. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.active", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "nextPaymentDate": 1729694400000, "remainingCycleCount": 5, "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription has become active. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription that transitioned to the active state. A timestamp indicating the date and time of the next scheduled payment, expressed in milliseconds since the Unix epoch. The number of billing cycles remaining for the subscription. For example, if the total cycle count is 6 and 1 cycle has been completed, the remaining cycle count will be `5`. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Cancelled Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/cancelled This event is triggered when a subscription is cancelled by the merchant. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.cancelled", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription has been cancelled. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription that was cancelled. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Checkout Opened Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/checkout_opened This event is triggered when a subscription's checkout page is opened by a customer. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.checkout_opened", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription's checkout page has been opened. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription whose checkout page was opened. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Created Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/created This event is triggered when a new subscription intent is successfully created. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.created", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription has been successfully created. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription that was created. This ID ties the event back to a particular subscription process. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Cycle Charged Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/cycle_charged This event is triggered when a subscription's billing cycle is successfully charged. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.cycle_charged", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "intentId": "in_fooBOwYsaK50AEfK", "intentAmount": 1500, "intentCurrency": "USD", "nextPaymentDate": 1732286400000, "remainingCycleCount": 4, "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription billing cycle has been successfully charged. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription that was charged for the current billing cycle. A unique identifier for the payment intent associated with this charge. This ID can be used to track the payment process and its status. The amount charged for the current billing cycle, expressed in the smallest unit of the currency. Here, `1500` represents 15.00 USD (as USD typically uses two decimal places). The currency used for the subscription payment. In this case, it is United States Dollars (USD). A timestamp indicating the date and time of the next scheduled payment, expressed in milliseconds since the Unix epoch. The number of billing cycles remaining for the subscription. For instance, if the total cycle count is 6 and 2 cycles have been completed, the remaining cycle count will be `4`. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Ended Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/ended This event is triggered when a subscription is successfully ended after all billing cycles. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.ended", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription has been successfully ended. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription that has been completed. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Paused Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/paused This event is triggered when a subscription is paused by the merchant. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.paused", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription has been paused. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription that was paused. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Payment Method Updated Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/payment_method_updated This event is triggered when a subscription's payment method is updated. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.payment_method_updated", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "nextPaymentDate": 1729694400000, "remainingCycleCount": 5, "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription's payment method has been updated. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription whose payment method was updated. A timestamp indicating the date and time of the next scheduled payment, expressed in milliseconds since the Unix epoch. The number of billing cycles remaining for the subscription. For example, if the total cycle count is 6 and 1 cycle has been completed, the remaining cycle count will be `5`. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Trialing Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/trialing This event is triggered when a subscription enters the trialing state—before it becomes fully active. It indicates the start of the trial period, during which the user can access the subscription benefits without being charged. The event includes details such as the subscription ID, upcoming payment date, remaining billing cycles, and optional metadata. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.trialing", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "nextPaymentDate": 1729694400000, "remainingCycleCount": 5, "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription has entered the trialing state. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription that transitioned to the active state. A timestamp indicating the date and time of the next scheduled payment, expressed in milliseconds since the Unix epoch. The number of billing cycles remaining for the subscription. For example, if the total cycle count is 6 and 1 cycle has been completed, the remaining cycle count will be `5`. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Unpaid Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/unpaid This event is triggered when a subscription becomes unpaid, indicating it is no longer active for billing. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.unpaid", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "nextPaymentDate": null, "remainingCycleCount": 2, "errorCode": "insufficient_funds", "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription has transitioned to an unpaid state. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription that has become inactive. The next payment date for the subscription. This will typically be `null` when the subscription becomes inactive. The number of billing cycles remaining for the subscription. For an inactive subscription, this will generally be `0`. A specific code indicating the reason for the subscription payment failure. This helps identify whether the failure was due to user error or processing error. For a complete list of error codes and their meanings, see our [Error Codes](/products/one-time-payments/error-codes) documentation. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Unpaused Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/subsEvents/unpaused This event is triggered when a subscription is unpaused by the merchant. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "subscription.unpaused", "eventTime": 1729608043615, "subscriptionId": "sub_fooBOwYsaK50AEfK", "nextPaymentDate": 1729608043615, "remainingCycleCount": 5, "metadata": { "orderId": "12345", "customerNote": "Deliver after 5 PM" } } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a subscription has been unpaused. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific subscription that was unpaused. The timestamp of the next scheduled payment for the subscription, in milliseconds since the Unix epoch (January 1, 1970). The number of billing cycles remaining for the subscription. A collection of key-value pairs that were provided when the object was created. These metadata values are echoed back in the response, allowing you to store and retrieve custom information such as context-specific attributes, references, or tags. This can be useful for correlating records in your system or attaching meaningful context to transactions. # Virtual Bank Account Transaction Source: https://docs.xpaycheckout.com/developer-resources/webhooks/events/vbaEvents/transaction This event is triggered when a credit lands in one of your merchant virtual bank accounts. A virtual bank account (VBA) transaction event is emitted whenever funds are received into a virtual bank account assigned to your account. Use it to reconcile incoming bank transfers in real time, matching each credit to the payer via its statement descriptor and recording the amount against your account. ```json theme={null} { "eventId": "whe_fooD944t4VUKkaDT", "eventType": "virtual_bank_account.transaction", "eventTime": 1729608043615, "transactionId": "vbatxn_fooBOwYsaK50AEfK", "amount": 50000, "currency": "USD", "transactionTimeStamp": 1729608043615, "statementDescriptor": "ACME CORP INV 1042" } ``` A unique identifier for this specific event. This ensures that each event can be tracked and processed individually. Describes the type of event. In this case, it signifies that a transaction has been received into a virtual bank account. The timestamp when the event was generated, typically in milliseconds since the Unix epoch (January 1, 1970). This value can be used to track when the event occurred. A unique identifier for the specific virtual bank account transaction. This ID ties the event back to the individual credit received into the account. The amount received, expressed in the smallest unit of the currency. Here, 50000 represents 500.00 USD (because USD uses two decimal places). The currency of the transaction, as a three-letter ISO 4217 code (e.g. `USD`). The timestamp when the underlying bank transaction occurred, in milliseconds since the Unix epoch. This reflects when the funds were credited to the account, which may differ from `eventTime`. The descriptor that appeared on the bank statement for this credit. Use it to identify the payer or reconcile the transfer against an invoice. # Webhooks Introduction Source: https://docs.xpaycheckout.com/developer-resources/webhooks/introduction Learn how to securely handle real-time events from xPay using webhooks. Webhooks allow you to stay informed about specific events in xPay by receiving real-time notifications. Here's everything you need to know about setting up and handling webhooks securely and efficiently. ### Webhook URL You will register an endpoint URL to receive events from xPay through the **[Settings Page](https://app.xpaycheckout.com/settings)**, where a `signing_key` will also be provided for securing the communication between xPay and your system. Make sure your webhook URL is set up to reliably accept these events and handle them as needed. Please ensure that you register the webhook endpoint via the **[Settings Page](https://app.xpaycheckout.com/settings)** to receive event notifications. The `signing_key` required for verifying the events will also be provided there. ### Timeouts xPay's system will adhere to a **2-second** connection timeout and read timeout for each webhook delivery attempt. If the request exceeds this limit or fails for any reason, xPay will retry sending the event using exponential backoff to avoid overwhelming your system. ### Idempotency To ensure robustness in your webhook processing, it's crucial to handle events idempotently. This means that even if the same event is sent multiple times (due to retries), your system will handle it without causing errors or duplicating operations. ### Security xPay supports two secure methods for verifying webhook authenticity: `HMAC-SHA512` and `ECDSA`. For implementation details, see the [Webhook Verification Guide](./verification). *** # Webhook Verification Source: https://docs.xpaycheckout.com/developer-resources/webhooks/verification xPay supports two methods for webhook signature verification. Both are valid and supported. Please use the one that matches your integration. ## 1. HMAC-SHA512 This is the default method. Each event payload is signed using HMAC-SHA512 with your provided `signing_key`. The signature is sent in the `xpay-signature` header. ```java Java theme={null} private boolean verifySignature(String incomingSignature, String payload, String secret) throws Exception { Mac sha512Hmac = Mac.getInstance("HmacSHA512"); SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA512"); sha512Hmac.init(keySpec); byte[] macData = sha512Hmac.doFinal(payload.getBytes("UTF-8")); incomingSignature.equals(Base64.getEncoder().encodeToString(macData)); } ``` ```javascript Node.js theme={null} const crypto = require('crypto'); function verifySignature(incomingSignature, payload, secret) { const hmac = crypto.createHmac('sha512', secret); hmac.update(payload); const generatedSignature = hmac.digest('base64'); return incomingSignature === generatedSignature; } // Usage example const incomingSignature = 'some-signature'; const payload = 'payload-data'; const secret = 'secret-key'; const isValid = verifySignature(incomingSignature, payload, secret); console.log(isValid); ``` ```python Python theme={null} import hmac import hashlib import base64 def verify_signature(incoming_signature, payload, secret): # Create the HMAC-SHA512 signature mac = hmac.new(secret.encode('utf-8'), payload.encode('utf-8'), hashlib.sha512) generated_signature = base64.b64encode(mac.digest()).decode('utf-8') return incoming_signature == generated_signature # Usage example incoming_signature = 'some-signature' payload = 'payload-data' secret = 'secret-key' is_valid = verify_signature(incoming_signature, payload, secret) print(is_valid) ``` ```rust Rust theme={null} // Add Dependencies in Cargo.toml // [dependencies] // hmac = "0.11" // sha2 = "0.10" // base64 = "0.13" use hmac::{Hmac, Mac}; use sha2::Sha512; use base64::{encode}; // Type alias for HMAC-SHA512 type HmacSha512 = Hmac; fn verify_signature(incoming_signature: &str, payload: &str, secret: &str) -> bool { let mut mac = HmacSha512::new_from_slice(secret.as_bytes()).expect("HMAC can take key of any size"); mac.update(payload.as_bytes()); let result = mac.finalize(); let generated_signature = encode(result.into_bytes()); incoming_signature == generated_signature } // Usage example fn main() { let incoming_signature = "some-signature"; let payload = "payload-data"; let secret = "secret-key"; let is_valid = verify_signature(incoming_signature, payload, secret); println!("{}", is_valid); } ``` ## 2. ECDSA xPay supports ECDSA signature verification for webhooks. The signature is sent in the `xpay-private-signature` header, and the public key is provided below. #### xPay Webhook Public Key This is the public key used for webhook signature verification. The key below is **base64 encoded**. You can use this key to verify ECDSA signatures from xPay webhooks. ```text theme={null} MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBlXbsIwGSYhdXBOtdrZr3L346JXi3dOg8vP9NCcTOV0ucLVl/GPi2ZVMsdBISQKTGIhzXY/gddRl846C27TfPw== ``` ```java Java theme={null} import java.security.*; import java.security.spec.*; import java.util.Base64; public class WebhookVerifier { public static boolean verifySignature(String publicKeyBase64, String signatureBase64, String payload) throws Exception { byte[] publicBytes = Base64.getDecoder().decode(publicKeyBase64); KeyFactory keyFactory = KeyFactory.getInstance("EC"); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes); PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature ecdsaVerify = Signature.getInstance("SHA256withECDSA"); ecdsaVerify.initVerify(pubKey); ecdsaVerify.update(payload.getBytes("UTF-8")); byte[] signatureBytes = Base64.getDecoder().decode(signatureBase64); return ecdsaVerify.verify(signatureBytes); } public static void main(String[] args) throws Exception { String publicKey = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBlXbsIwGSYhdXBOtdrZr3L346JXi3dOg8vP9NCcTOV0ucLVl/GPi2ZVMsdBISQKTGIhzXY/gddRl846C27TfPw=="; String signature = "MEUCIQDncKxd1HEthoRD/+kX2Kw0ZKRbaewtX9IfvW5vE/MPMwIgZ/BLckOaRkHqP3mtIX4DQRRKLXvmt9mmWG3mKMNUZPI="; String payload = "{\"eventId\":\"whe_g00AGgDy9KeiTPj6\",...}"; boolean isValid = verifySignature(publicKey, signature, payload); System.out.println("Signature valid: " + isValid); } } ``` ```javascript Node.js theme={null} const crypto = require('crypto'); function verifySignature(publicKeyBase64, signatureBase64, payload) { const publicKeyPem = `-----BEGIN PUBLIC KEY-----\n${publicKeyBase64.match(/.{1,64}/g).join('\n')}\n-----END PUBLIC KEY-----`; const verifier = crypto.createVerify('SHA256'); verifier.update(payload); verifier.end(); const signature = Buffer.from(signatureBase64, 'base64'); return verifier.verify(publicKeyPem, signature); } // Example usage const isValid = verifySignature( "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBlXbsIwGSYhdXBOtdrZr3L346JXi3dOg8vP9NCcTOV0ucLVl/GPi2ZVMsdBISQKTGIhzXY/gddRl846C27TfPw==", "MEUCIQDncKxd1HEthoRD/+kX2Kw0ZKRbaewtX9IfvW5vE/MPMwIgZ/BLckOaRkHqP3mtIX4DQRRKLXvmt9mmWG3mKMNUZPI=", '{"eventId":"whe_g00AGgDy9KeiTPj6",...}' ); console.log('Signature valid:', isValid); ``` ```python Python theme={null} import base64 from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.serialization import load_der_public_key def verify_signature(public_key_base64, signature_base64, payload): public_key_bytes = base64.b64decode(public_key_base64) public_key = load_der_public_key(public_key_bytes) signature = base64.b64decode(signature_base64) try: public_key.verify(signature, payload.encode('utf-8'), ec.ECDSA(hashes.SHA256())) return True except Exception: return False # Example usage is_valid = verify_signature( "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBlXbsIwGSYhdXBOtdrZr3L346JXi3dOg8vP9NCcTOV0ucLVl/GPi2ZVMsdBISQKTGIhzXY/gddRl846C27TfPw==", "MEUCIQDncKxd1HEthoRD/+kX2Kw0ZKRbaewtX9IfvW5vE/MPMwIgZ/BLckOaRkHqP3mtIX4DQRRKLXvmt9mmWG3mKMNUZPI=", '{"eventId":"whe_g00AGgDy9KeiTPj6",...}' ) print("Signature valid:", is_valid) ``` ```rust Rust theme={null} use base64; use ring::{signature, signature::UnparsedPublicKey}; fn verify_signature(public_key_b64: &str, signature_b64: &str, payload: &str) -> bool { let public_key_bytes = match base64::decode(public_key_b64) { Ok(bytes) => bytes, Err(_) => return false, }; let signature_bytes = match base64::decode(signature_b64) { Ok(bytes) => bytes, Err(_) => return false, }; let public_key = UnparsedPublicKey::new(&signature::ECDSA_P256_SHA256_ASN1, &public_key_bytes); public_key.verify(payload.as_bytes(), &signature_bytes).is_ok() } fn main() { let valid = verify_signature( "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBlXbsIwGSYhdXBOtdrZr3L346JXi3dOg8vP9NCcTOV0ucLVl/GPi2ZVMsdBISQKTGIhzXY/gddRl846C27TfPw==", "MEUCIQDncKxd1HEthoRD/+kX2Kw0ZKRbaewtX9IfvW5vE/MPMwIgZ/BLckOaRkHqP3mtIX4DQRRKLXvmt9mmWG3mKMNUZPI=", r#"{"eventId":"whe_g00AGgDy9KeiTPj6",...}"# ); println!("Signature valid: {}", valid); } ``` *** ### Sample Payload Header ```json theme={null} { "xpay-signature" : "s3z2v3ZGwMvDwiQ+9PpAT3WuSYU+PeSZJqvdzZXPmifAh3sT+s502PgJJx9NV4KQaScEaquTEuHJ30v17hK5GA==", "xpay-private-signature" : "MEYCIQD+649oWWsMkVbTcOsfkxKvxsnbAPbeq0QHptC2i1dFuwIhALN5GHEliiv+MT3/5a2ye8Wbud5rFNDRIMz6ExgWAaYg", ... } ``` *** # Klarna FAQs for Merchants Source: https://docs.xpaycheckout.com/faqs/klarna-overview Comprehensive guide to Klarna integration, payment options, and requirements for merchants using xPay ### In which geographies can Klarna be used? > Currently, Klarna on xPay is supported only for **U.S.-based customers using USD**. Non-U.S. cards or billing addresses are not supported. ### What payment options does Klarna offer? > Klarna provides multiple financing plans based on the consumer's credit profile: > > | Plan Type | Typical Interest APR\* | Amount Eligibility | > | ----------------------- | ---------------------- | ------------------ | > | Pay in 4 (bi-weekly) | 0% | 35 to 2,500 USD | > | Pay in 3 (monthly) | 0% to 13.99% | 149 to 10,000 USD | > | 6-Month Plan (monthly) | 7.99% to 19.99% | 149 to 10,000 USD | > | 12-Month Plan (monthly) | 8.99% to 23.99% | 149 to 10,000 USD | > > *Ranges are indicative, based on observed data. While Klarna's official APR range goes up to 35.99%, the highest rates we've seen across customers with lowest credit quality would be 25-28%.* ### How is Klarna's credit decisioning handled? > Klarna underwrites each transaction individually using a **soft credit pull**. The following factors are considered: > > * Customer's credit score > * Existing Klarna balances > * Billing/shipping address match > * Transaction amount > * General risk signals based on account activity **Important**: Merchants are not involved in approval decisions – Klarna independently assesses each transaction. ### What are the consumer requirements to use Klarna? > To be eligible, a user must have: > > * A valid **U.S.-issued debit card** (credit cards are not accepted for repayments) > * A **U.S. billing address** > * Be **18+ years old** > * A valid **Social Security Number (SSN)** > * A credit profile that meets Klarna's internal approval thresholds ### Why might a Klarna transaction be declined? > Common reasons include: > > * Low or insufficient credit score > * Existing unpaid Klarna balances > * Mismatch in billing and shipping addresses > * High-risk transaction patterns > * Incorrect billing information > * Attempt to pay in a non-supported currency or from a non-U.S. card ### Can users see their exact APR and plan before confirming? > **Yes**. Klarna presents the exact APR, tenure, and payment schedule before the user confirms the transaction, ensuring full transparency. ### How are late or missed payments handled? > Klarna charges a late fee equal to **25% of the missed installment amount**, capped at a maximum of **\$7**. ### Can consumers repay using a credit card? > **No**. Klarna only accepts debit cards or linked bank accounts for repayments. This is to prevent users from paying off credit with more credit and to promote responsible borrowing. # Frequently Asked Questions Source: https://docs.xpaycheckout.com/faqs/overall-faq ## **Product FAQs** To begin collecting payments, refer to the [onboarding section](/get-started/onboarding) of our documentation. It will guide you step-by-step through the process. xPay is compatible with over 100+ countries including the United States, United Kingdom, India, Germany, France, Canada, and many more. xPay supports transactions in 20+ currencies like USD, EUR, GBP, INR, and many others. You can find the full list of supported currencies in the [Currencies Supported](/get-started/currencies-supported). Yes, xPay supports subscription and recurring payments. Recurring payments functionality is being expanded, with more features coming soon. Yes, you can create a single link for multiple payments via xPay's dashboard. Refer to the guide here: [https://www.youtube.com/watch?v=VDnlGNdWrQM](https://www.youtube.com/watch?v=VDnlGNdWrQM) xPay automatically detects whether a customer’s device supports Apple Pay or Google Pay and displays those options in real time. Both Apple Pay and Google Pay are device-specific payment methods, since the card details are securely stored on the customer’s device.

If you're expecting to see Apple Pay but don't, make sure you're opening the payment link on an iOS device with a VPN set to a country where apple pay is support (eg. USA) and have apple wallet app set up correctly. Apple Pay is not supported in India.

Similar to above, If you're expecting to see Google Pay but don't, make sure you're opening the payment link on an Android device with a US VPN and have Google Pay app set up correctly. Google Pay in India is different from Google Pay used internationally. In India, it functions as a UPI app, while outside India it works as a digital wallet for cards.
No. Separate whitelisting for apple pay is not required. Use **Bulk Refund** to refund up to 200 payments in one go by uploading a CSV of intent IDs. You need the **Transactions › Refund & Cancel** permission. On the **Transactions** page, click the **⋯** button next to **Export** and choose **Bulk Refund**. The Transactions page with the ⋯ menu open, showing Bulk Refund Click **Download CSV Template**. Keep the `intentId` header and add one intent ID per row. Then click **Upload CSV** and select your file. The Bulk Refund dialog with Download CSV Template, Upload CSV and the history of past runs Review the prompt and click **Confirm refund**. Refunds can't be undone. The Start bulk refund? confirmation dialog Refunds run in the background. When the run finishes, you're emailed a report, and you can also download it from the **Report** column in the Bulk Refund dialog. It shows the result and refund ID for each payment. **Good to know** * Each payment is refunded for its **full remaining amount**. Custom or partial amounts aren't supported, so use a single refund for those. * Only successful or partially refunded payments can be refunded. Fully refunded and disputed payments, and payments without enough balance, are skipped and listed in the report. * Only one bulk refund can run at a time. A submitted run can't be cancelled. * **Completed** means the run has finished, not that every refund succeeded, so always check the report. To retry failed payments, upload them in a new CSV. * Each refund triggers the usual refund webhook. Customers get a refund email if your Refund Success email setting is on. *** ## **Tech FAQs** We follow Basic Auth RFC for authentication. In basic HTTP authentication, a request contains a header field in the form of `Authorization: Basic `, where `` is the [Base64](https://en.wikipedia.org/wiki/Base64) encoding of `` and `` joined by a single colon `:`. For a detailed explanation of how to use xPay keys, refer to the [Authentication Page](/developer-resources/authentication). All values in the `amount` field must be in the smallest currency unit. For example: - If the transaction is in USD, 1 USD = 100 cents, so to charge USD 2, you should set the amount to 200. - Similarly, for EUR, 1 EUR = 100 cents. A 400 Bad Request error usually means there’s something wrong with the request. This can be due to: * Incorrect parameters * Missing required fields * Issues with authentication or malformed data Check your API call and ensure all required parameters are correct and properly formatted. Also, verify your xPay API keys and ensure they’re correctly included in the header. For a more detailed description of error codes and troubleshooting tips, refer to the [Errors](/developer-resources/errors). You can integrate xPay with your platform using our well-documented API. The integration process includes authentication, creating a payment intent, handling the payment process, and confirming the payment. Refer to the [API Integration Guide](/products/one-time-payments/architecture) for step-by-step details. xPay collects essential billing details required to complete and verify payments. This includes: * Full name * Email address * Contact number (optional) * ZIP code * Country These details help ensure accurate billing and compliance with payment regulations. **Yes**. You can export up to two years of transaction and payout data directly from your xPay dashboard in CSV format. This is helpful for accounting, audits, or internal reporting. *** ## **Payment Failure Messages** This message comes directly from the customer’s bank, usually when their **card is not enabled for international transactions.** Ask the customer to check with their bank and enable international payments. *** ## **Product Guides** You can refer to the guide here: [https://www.loom.com/share/4ecffc1ecff543fab89449aa01736425?sid=61309c8f-6a9f-4489-90bb-8fa4fbaa88ba](https://www.loom.com/share/4ecffc1ecff543fab89449aa01736425?sid=61309c8f-6a9f-4489-90bb-8fa4fbaa88ba) *** If you need more assistance or have additional questions, feel free to contact our support team at [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com). # Prohibited Activities / Businesses Source: https://docs.xpaycheckout.com/faqs/prohibited-businesses Activities, products, and services considered prohibited under xPay's terms of service. The activities, products, and services listed below are considered "Prohibited Activities / Businesses" for the purposes of xPay's services. By using xPay's services, each Seller or Merchant confirms that it does not, and will not, engage in any of the Prohibited Activity / Business. xPay may immediately reject, suspend, or offboard any Seller / Merchant found to be engaged in a Prohibited Activity / Business. xPay may also recover from the Seller or Merchant any losses, costs, damages, fines, penalties, or other amounts incurred as a result of: * Any court or regulatory action; or * Any action or penalty imposed by a card network, payment service provider, or other payment partner in connection with engagement in such Prohibited Activity / Business by the Merchant / Seller. xPay may recover these amounts by deducting them from any current or future payments due to the Seller or Merchant, or by issuing a separate demand for payment. ## Prohibited Activities / Businesses * Gambling and betting * Real money online games * Unlicensed lotteries * Alcohol or alcoholic beverages, tobacco, cigarettes and related products * Body parts, including organs * Pornographic or adult content, including child sexual abuse material or child pornography * Escort or prostitution services * Illegal drugs, narcotics, psychotropic substances, or other controlled substances * Live animals and hides / skin / teeth / nails and other parts of animals * Fake documents or government IDs * Firearms, ammunition, explosives, regulated corrosive substances, toxic substances, or weapons sold without appropriate licences * Counterfeit or infringing goods or content, including unauthorised copies of copyrighted media including books * Unauthorised copies of software, video games or other licensed or protected materials * Copyright unlocking devices, hacking or cracking tools or software * Miracle cures or remedies, marketed as quick health fixes * Offensive goods, literature or other media, which (a) defame or slander any person or group of persons; (b) encourage or incite violence; or (c) promotes hatred * Insurance policies and investment products and schemes * Unregulated financial, investment, or money circulation schemes * Cryptocurrency, virtual currencies, and other virtual digital assets * Multi-level marketing collecting fees * Currency or currency derivatives or other capital transactions * Any product or service which is not in compliance with all applicable laws and regulations whether federal, state, local or international * Any products / services that have the potential of casting xPay in a poor light and / or that may be prone to buy and deny attitude of the cardholders when billed and thus leading to chargeback and fraud losses * Products / services / activities that are either prohibited by any regulator having jurisdiction over the relevant activity / product / service, or operated without appropriate licenses / authorisation from such regulator * Any other product / service / activity prohibited under applicable law in the jurisdiction of the seller or the buyer # xPay Card Installments Source: https://docs.xpaycheckout.com/faqs/x-pay-card-installments ### 1. What is xPay Card Installments? > xPay Card Installments lets customers split a purchase into smaller monthly payments **using their existing credit card**. There's no new loan, no credit application, and no separate BNPL account. The customer simply pays in easy monthly chunks on a card they already have. ### 2. Why should a merchants offer card installments over other BNPL like Klarna? > * **Higher conversion** — removes KYC friciton on big-ticket purchases. > * **Higher AOV** — customers are more comfortable upgrading when monthly cost feels manageable. > * **Zero credit risk for the merchant** — xPay confirms the customer's card can cover the full amount upfront. > * **No new lending relationship** — customers keep their existing card benefits (rewards, fraud protection, purchase insurance). ### 3. How xPay Installments Works? > 1. Customer picks a plan (e.g., 6 or 12 months) at checkout. > 2. xPay confirms with the card issuer that there's enough available credit for the full purchase amount. > 3. The **first installment** is charged immediately (or upon shipping, depending on merchant config). > 4. xPay automatically charges the card **once a month** until the plan is complete. ### 4. What is an authorization hold? > | Term | What It Is? | > | :---------------- | :------------------------------------------------------------------------------------------------------------------------------------------- | > | **Payment** | An actual monthly charge debited from the card. This is the installment amount. | > | **Authorization** | A temporary hold on the **remaining balance**, it's a verification, **not a charge**. It ensures the plan can continue without interruption. | An authorization is **not** a real charge. It is released within **4–28 days** depending on the issuing bank. However, some banks label it as *"**pending**"* in statements, which confuses customers **and even bank staff**. If a customer or their bank flags this, explain that it's a standard temporary hold and will drop off automatically ### 5. Will the customer need enough credit for the full amount? > **Yes, at setup only.** The customer must have available credit equal to the full purchase price when first creating the plan. After that, they're only charged the installment amount each month. ### 6. Is there a limit on the maximum purchase amount for xPay Card Installments? > Yes — the limit is **20,000 USD** per transaction. Orders above that won't show installment options at checkout and must be paid in full. > > Customers still need enough available credit to cover the full amount at setup, so a purchase near the limit only qualifies if their card allows it. *** ## Credit & Card Support ### 1. Will using xPay Installments affect the customer's credit score? > **No.** No credit check is performed. ### 2. Which credit cards are supported? > Depends on the merchant plan, but typically: > > * ✅ **Visa** > * ✅ **Mastercard** > * ✅ **American Express** > * ✅ **Discover** > * ✅ **UnionPay** > > Supported cards are clearly shown at checkout. ### 3. Can customers pay with a debit card? > **No.** Only credit cards are accepted at this time. *** ## Fees ### 1. Why is there a convenience fee on card installments? > The convenience fee (typically 6–9%) covers: > > * **Payment processing** & card network costs across multiple transactions. > * **Authorization management** over the life of the plan. > * **Risk coverage** - xPay guarantees the merchant gets paid even if the customer defaults later. > > **How to position it:** *"It's a small fee for the flexibility of paying over time and unlike a personal loan, there's no interest, no credit check, and no new account."* *** ## Payment Failures & Retries ### 1. What happens if a customer's installment payment fails? > 1. The customer receives a notification to update their card or ensure sufficient funds. > 2. If it continues to fail, the remaining balance may be captured from the authorization. ### 2. How many times can I ask the customer to retry? > **2–3 attempts maximum.** Beyond that, it creates a poor experience and increases failure. If the payment still fails after 3 attempts: > > * Reach out to understand the issue (expired card, insufficient funds, bank block). > * Offer to update the card on file. > * If unresolved, escalate to xPay support. Do **not** retry more than **3 times**. Excessive retries can trigger fraud flags at the issuing bank and damage the merchant's processing reputation. *** ## Common Customer Quesiotns & How to Handle Them? ### 1. "I see a large pending charge on my card!" > **Response:** *"That's an authorization hold, not a charge. Your bank is confirming your card can support the plan. It will drop off within a few days. You'll only be charged your monthly installment amount."* > > Image ### 2. "My bank says I was charged the full amount!" > **Response:** *"Some banks display authorizations as pending charges but no money has left your account beyond the installment. If needed, we can provide a transaction breakdown you can share with your bank."* ### 3. "I don't want a credit check." > **Response:** *"There is no credit check at all. xPay uses your existing credit card and no new applications, no hard pulls, no bureau reporting."* ### 4. "Why can't I use my debit card?" > **Response:** *"xPay works by placing a temporary authorization on a credit line, which debit cards don't support. We're limited to credit cards for now."* # Currencies Supported Source: https://docs.xpaycheckout.com/get-started/currencies-supported List of all currencies supported by xPay xPay supports a wide variety of currencies to facilitate global transactions. Below is the list of all supported currencies with their respective currency code and amount limits. | Currency Code | Currency Name | Minimum Amount | Maximum Amount | | ------------- | ------------------- | -------------- | -------------- | | AED | UAE Dirham | 2 | 999999.99 | | ARS | Argentine Peso | 500 | 999999.99 | | AUD | Australian Dollar | 0.95 | 999999.99 | | BDT | Bangladeshi Taka | 65 | 999999.99 | | BRL | Brazilian Real | 3 | 999999.99 | | BWP | Botswana Pula | 8 | 999999.99 | | CAD | Canadian Dollar | 0.8 | 999999.99 | | CNY | Chinese Yuan | 4 | 999999.99 | | DKK | Danish Krone | 4.25 | 999999.99 | | EUR | Euro | 0.5 | 999999.99 | | GBP | Great British Pound | 0.4 | 999999.99 | | HKD | Hong Kong Dollar | 4 | 999999.99 | | HUF | Hungarian Forint | 200 | 999999.99 | | ILS | Israeli Shekel | 2 | 999999.99 | | INR | Indian Rupee | 50 | 9999999.99 | | KES | Kenyan Shilling | 80 | 999999.99 | | LKR | Sri Lankan Rupee | 165 | 999999.99 | | MXN | Mexican Peso | 11.5 | 999999.99 | | MYR | Malaysian Ringgit | 2.5 | 999999.99 | | NGN | Nigerian Naira | 900 | 9999999999.99 | | NOK | Norwegian Krone | 6 | 999999.99 | | NPR | Nepalese Rupee | 80 | 999999.99 | | NZD | New Zealand Dollar | 0.95 | 999999.99 | | PHP | Philippine Peso | 30 | 999999.99 | | PKR | Pakistani Rupee | 150 | 999999.99 | | PLN | Polish Zloty | 2 | 999999.99 | | QAR | Qatari Riyal | 2 | 999999.99 | | RUB | Russian Ruble | 50 | 999999.99 | | SAR | Saudi riyal | 2 | 999999.99 | | SEK | Swedish Krona | 6 | 999999.99 | | SGD | Singapore Dollar | 0.8 | 999999.99 | | TRY | Turkish Lira | 20 | 999999.99 | | UAH | Ukrainian Hryvnia | 30 | 999999.99 | | USD | US Dollar | 0.85 | 999999.99 | | ZAR | South African Rand | 10 | 999999.99 | *** If you need or want to add any specific currency, feel free to contact us at [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com). # Introduction Source: https://docs.xpaycheckout.com/get-started/introduction Welcome to xPay Documentation! Hero Light Hero Light This guide is designed to equip you with all the essential resources, tools, and insights to seamlessly integrate and utilize xPay’s robust payment solutions. Whether you are a developer, business owner, or partner, this documentation will guide you through the full range of xPay’s features and functionalities. Our goal is to provide you with a comprehensive understanding of the platform—from API integrations to advanced features. Throughout this documentation, you’ll find detailed explanations, code samples, and best practices to help you maximize the full potential of xPay. ## About xPay xPay is an international payment gateway that lets Indian businesses accept payments in 30+ currencies and 100+ countries with just a single integration. We specialise in processing payments via cards and local payment methods like wallets. A few key details about xPay * 48 hour onboarding * Accept Visa, Mastercard, Amex, Discover from 100+ countries * Works best for USD, and 30+ other currencies * We also provide Virtual account solutions in these currencies Learn more at [https://www.xpaycheckout.com/](https://www.xpaycheckout.com/) ## Who Should Use This Documentation This documentation is intended for: * **Founders & PMs**: The founder or Payments PM setting up xPay * **Engineers**: The engineers working on xPay integration ## Frequenty Asked Questions Check out our [FAQs](/help/faq) for answers to common questions about xPay. ## Contacting Support Contact us for support at [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com) # Onboarding Source: https://docs.xpaycheckout.com/get-started/onboarding In this section, we'll guide you through the initial steps to get started with xPay Below process end to end takes less than 2 minutes ### Account Creation and KYB Onboarding Register at [https://app.xpaycheckout.com/user-register](https://app.xpaycheckout.com/user-register), then sign in. After signing in, you will be automatically redirected to the onboarding page where you can go through the KYB flow and submit documents to complete your verification. It typically takes upto 48 hours for your account to be verified and approved. Once your account is approved, you should receive an email. Sign in at [https://app.xpaycheckout.com/login](https://app.xpaycheckout.com/login) to start collecting real-world payments. *** # Payment Methods Source: https://docs.xpaycheckout.com/get-started/payment-methods-supported xPay supports a wide range of payment methods to ensure global compatibility. The table below provides a detailed breakdown of the available payment methods on xPay's platform. | **Category** | **Payment Methods** | | -------------------------------------- | --------------------------------------------------------------- | | **Cards (Default)** | Visa, Mastercard, American Express, Discover, Diner's Club, JCB | | **Wallets** | Amazon Pay, Apple Pay, Cash App, Google Pay, PayPal | | **BNPL (Buy Now, Pay Later)** | Afterpay, Klarna | | **EMI (Equated Monthly Installments)** | Card Installments | *** ### **Payment Method Enums** | **Enum Name** | **Description** | | ------------------ | ------------------------------------------------------- | | `CARD` | Credit and debit card payments (Visa, Mastercard, etc.) | | `AMAZON_PAY` | Pay through Amazon accounts | | `APPLE_PAY` \* | Digital wallet for Apple devices (requires `CARD`) | | `CASH_APP` | US-based digital payment app | | `GOOGLE_PAY` \* | Secure payment platform by Google (requires `CARD`) | | `PAYPAL` | Online payments via PayPal accounts | | `AFTERPAY` | Buy now, pay later service | | `KLARNA` | European BNPL service | | `CARD_INSTALLMENT` | Credit Card Installments (Equated Monthly Installments) | *** ### Payment Method Scopes | **Method** | **Active Geographies** | **Currency Rules** | | --------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------- | | **Card** | Global | Any [supported currency](/get-started/currencies-supported) | | **Amazon Pay** | US | USD only | | **Apple Pay** | Global (except India) | Any [supported currency](/get-started/currencies-supported) | | **Cash App** | US | USD only | | **Google Pay** | Global (except India) | Any [supported currency](/get-started/currencies-supported) | | **PayPal** | Global\* | Initial charge in USD → then local currency inside PayPal flow | | **Afterpay** | US and Canada | USD only *(visible for amounts ≤ \$4000)* | | **Klarna** | US and Canada | USD only | | **Card Installments** | Global | Initial charge in USD → then Customer from any geography can complete the payment *(amount range \$500–\$10,000)* | \* The initial currency for **PayPal** needs to be USD on xPay. Once user enters PayPal's flow, they can pay in their **local currency**. [Watch demo](https://drive.google.com/file/d/18U1AnmL0ZIYqfSEZR5CXIAoR7cHa_Wb7/view?usp=drive_link) *** ### **Details on Payment Methods** * **Cards (Default)**: This is the default payment method enabled for all xPay accounts. You can accept payments from major credit and debit cards such as: \ [Visa](https://www.visa.com) | [Mastercard](https://www.mastercard.com) | [American Express](https://www.americanexpress.com) | [Discover](https://www.discover.com) | [Diner's Club](https://www.dinersclub.com) | [JCB](https://www.global.jcb/en) and many more. * **Wallets**: Wallets allow your customers to pay using popular digital payment platforms. If you need to enable any of the following, please contact us: \ [Amazon Pay](https://pay.amazon.com) | [Apple Pay](https://www.apple.com/apple-pay/) | [Cash App](https://cash.app) | [Google Pay](https://pay.google.com) | [PayPal](https://www.paypal.com) * **BNPL (Buy Now, Pay Later)**: Let your customers split payments over time using BNPL services. Enable the following options upon request: \ [Afterpay](https://www.afterpay.com) | [Klarna](https://www.klarna.com) * **EMI (Equated Monthly Installments)**: This is a proprietary payment method build by xPay which lets yout customers split their Credit Card payments over time. Enable the following upon request:\ [Card Installments](https://www.xpaycheckout.com/) *** ### **Refunds** Full and partial refunds are supported on all payment methods. Refund windows vary by provider: | Provider | Refund Window | | ----------------------------------------------------- | ----------------------------------------------------------------------- | | **Cash App** | 90 days | | **Afterpay** | 120 days | | **Klarna, Amazon Pay** | 180 days | | **PayPal** | 24 months | | **Cards & derivative methods** (wallets/installments) | \~12 months *(varies by issuing bank; later refunds commonly rejected)* | Refunds past these windows will fail and must be reimbursed outside xPay. *** By default, **Cards** are enabled. You can contact us at [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com) to activate additional payment methods based on your business needs. *** # Argus Source: https://docs.xpaycheckout.com/products/argus/overview xPay's in-house intelligence and fraud prevention system. ## What is Argus? Argus is xPay's in-house intelligence and fraud prevention system. It evaluates payment risk automatically and helps merchants reduce repeat card fraud by identifying and blocking risky payment signals. You can also opt in to contribute your own risk signals. If your business logic flags a card as risky, block its fingerprint and Argus will apply that signal to future payments. For example, you can monitor [Early Fraud Warning (EFW) events](/developer-resources/webhooks/events/intentEvents/early_fraud_warning) and proactively block fingerprints according to your business logic. Use the [Block fingerprint by intent API](/developer-resources/endpoints/argus/block-fingerprint-by-intent) to add the card fingerprint from a successful payment intent to your merchant's blocklist. # Error Codes Source: https://docs.xpaycheckout.com/products/one-time-payments/error-codes When a payment fails, xPay provides specific error codes to help identify the reason for the failure. Below is a comprehensive list of possible error codes and their meanings. These error codes are currently visible in the exported CSV from the transactions page of your dashboard.\ \ In the below table,\ \[U] : Signifies that the failure reason was a user error\ \[X] : Signifies that the failure reason was not a user error but a processing error | **Error Code** | **Description** | | ----------------------------------- | ---------------------------------------------------------------------------- | | `card_decline` | \[X] The payment has been declined by the customer's bank. | | `expired_card` | \[U] The card has expired. | | `invalid_cvc` | \[U] The CVC code is incorrect. | | `invalid_address` | \[U] The address information code is incorrect. | | `insufficient_funds` | \[U] The card has insufficient funds. | | `incorrect_card_number` | \[U] The card number is incorrect. | | `threeDS_authentication_failure` | \[U] 3D Secure authentication failed. | | `timed_out` | \[U] The payment process timed out. | | `payment_method_decline` | \[X] The payment method was declined. | | `generic_decline` | \[X] The payment was declined. | | `issuer_decline` | \[X] The payment was declined by the issuer. | | `technical_issue` | \[X] The transaction could not be processed due to an internal server issue. | | `risk_check_failed` | \[X] The payment method failed risk checks. | | `setup_method_authorisation_failed` | \[X] Failed to authorise test payment on the payment method. | | `setup_method_indian_cards` | \[X] Cards issued in India are not supported for authorisation. | | `invalid_amount` | \[X] The payment method doesn't support this amount. | | `card_rate_limit_exceeded` | \[X] Card rate limit exceeded. Please try again later. | | `fraudulent` | \[X] The payment is suspected to be fraudulent. | | `lost_card` | \[X] The payment method has been reported lost/stolen. | | `processing_error` | \[X] The payment network encountered an error. Please try the payment again. | | `transaction_not_allowed` | \[X] This type of transaction is not allowed on this payment method. | For more information about handling failed payments, see our [Payment Statuses](/products/one-time-payments/payment-statuses) documentation. # Integration Process Source: https://docs.xpaycheckout.com/products/one-time-payments/integrationProcess Discover how to integrate xPay’s payment flow into your website using xPay’s payment gateway APIs. ```mermaid theme={null} sequenceDiagram participant MF as Merchant Frontend participant MS as Merchant Server participant XS as xPay Server participant XC as xPay Checkout autonumber rect transparent Note over MF, MS: User clicks "Pay" on Merchant Frontend MF ->> MS: Request to create payment end rect transparent Note over MS, XS: Initiate payment intent MS ->> XS: POST /create-intent {amount, currency, callbackUrl, ...} XS -->> MS: { xIntentId, fwdUrl } end rect transparent Note over MS, MF: Forward intent data MS -->> MF: Send fwdUrl and xIntentId end rect transparent Note over MF, XC: Redirect to xPay Checkout MF ->> XC: Open fwdUrl end rect transparent Note over XC, XS: User completes checkout XS ->> MS: Webhook intent. { xIntentId, ... } XS -->> MF: Redirect to callbackUrl?xpay_intent_id end rect transparent Note over MF, MS: Frontend queries status from backend MF ->> MS: GET /payment-status?xpay_intent_id MS -->> MF: { status: SUCCESS | FAILED } MF -->> MF: Display page based on status end ``` Start the transaction by making a **create-intent** POST request to xPay's API from the Merchant Server, which returns an `fwdUrl` in the response. See [create-intent API](/developer-resources/endpoints/payments/create-intent) for details. The **callbackUrl** string in the **create-intent** request should be configured to your client-side page responsible for managing the redirect from xPay checkout following a payment attempt. Once the payment intent is created, the xPay Server will respond with an `xIntentId`, which is used to track the payment status throughout the transaction. The Merchant Server should log or store this identifier for future reference. The Merchant Server forwards the intent data with `fwdUrl` to the Merchant Frontend, enabling it to manage user interactions related to the payment. Ensure the frontend is ready to handle the payment initiation process. Redirect the user to xPay’s checkout page to initiate the payment using the `fwdUrl`. ```javascript JavaScript theme={null} const redirectToCheckout = () => { const url = new URL(fwdUrl); // fwdUrl received from your server after creating an intent window.open(url.href).focus(); }; ``` #### Optional checkout parameters Append these query parameters to the `fwdUrl` to change how the checkout page looks. Keep every parameter already in the `fwdUrl` and add these to it. The checkout is currently available in **English and German only**. | Parameter | Values | What it does | | -------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `locale` | `en`, `de` | Opens the checkout in English or German. These are the only supported languages today. Defaults to the language the customer last chose, otherwise English. Any other value falls back to English. | | `scfa` | `true`, `false` | `false` hides the convenience fee amount. | | `hideCloseBtn` | `true`, `false` | `true` hides the checkout's close button. | ```javascript theme={null} const redirectToCheckout = () => { const url = new URL(fwdUrl); url.searchParams.set("locale", "de"); // open the checkout in German url.searchParams.set("scfa", "false"); // hide the convenience fee amount url.searchParams.set("hideCloseBtn", "true"); window.location.href = url.toString(); }; ``` `scfa=false` only hides the fee amount. The convenience fee label stays, the fee remains in the total, and the customer is charged the same. It changes what's displayed, nothing else. `locale` translates the checkout page only. Emails and some payment errors stay in English. * Once the checkout is completed, xPay will send a **webhook** to the Merchant Server with the final payment status: * [intent.success](/developer-resources/webhooks/events/intentEvents/success) for successful payments * [intent.failed](/developer-resources/webhooks/events/intentEvents/failed) for failed payments * Both webhooks include the `xIntentId` and other relevant payment details. * Simultaneously, the customer will be redirected to your configured **callbackUrl** with the query parameter **xpay\_intent\_id**. * Your Merchant Frontend should display the final result based on the status already received via the webhook. ```javascript JavaScript theme={null} const onPageLoad = async () => { const url = new URL(window.location.href); const intentId = url.searchParams.get("xpay_intent_id"); // At this point, your backend has already received the webhook. // You can show a confirmation page, or query your backend if needed. const status = await fetch(`/payment-status?xpay_intent_id=${intentId}`); if(status === "SUCCESS") { // redirect to your payment success page } else { // redirect to your payment failure page } }; ``` Always trust the **webhook** as the source of truth for payment status. The redirect is primarily for user experience. *** By following this process, you can integrate xPay's payment gateway into your website, ensuring reliable status tracking via **webhooks** and a seamless customer redirect flow. *** # Overview Source: https://docs.xpaycheckout.com/products/one-time-payments/overview Accept instant payments for individual transactions with xPay's secure and reliable one-time payment solution. ## What is One Time Payments? One Time Payments is designed for businesses that need to process individual transactions where customers pay once for a product or service. This solution provides a seamless payment experience with instant processing and real-time status updates. *** ## Getting Started Ready to integrate One Time Payments? Follow our step-by-step guide:   Start Integration } href="/products/one-time-payments/integrationProcess" />   Status Tracking } href="/products/one-time-payments/payment-statuses" />   Webhooks } href="/developer-resources/webhooks/events/intentEvents" />   API Endpoints } href="/developer-resources/endpoints/payments" />   Error Codes } href="/products/one-time-payments/error-codes" /> # Payment Statuses Source: https://docs.xpaycheckout.com/products/one-time-payments/payment-statuses The **xIntentId** tracks the lifecycle of a payment intent. Below is a table outlining the different statuses that an **xIntentId** can have during the payment process and what each status indicates. | **Status** | **Description** | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `CREATED` | The payment intent has been successfully created, but no payment has been initiated yet. | | `AUTHORIZED` | The payment has been successfully authorized and is ready to be captured. | | `SUCCESS` | The payment was processed successfully, and the transaction is complete. | | `FAILED` | The payment attempt failed due to various possible reasons. When a payment fails, you'll receive a specific error code. See our [Error Codes](/products/one-time-payments/error-codes) documentation for a complete list of possible error codes and their meanings. | | `CAPTURE_FAILED` | The attempt to capture an authorized payment failed. You'll receive a specific error code describing the reason for the failure. See our [Error Codes](/products/one-time-payments/error-codes) documentation for possible error codes and their meanings. | | `CANCELLED` | The payment was cancelled by the merchant or user before it was completed. | | `REFUNDED` | The payment was successfully processed but has since been fully refunded to the customer. | | `PARTIALLY_REFUNDED` | A portion of the original payment amount has been refunded to the customer. | *** # Saved Cards Source: https://docs.xpaycheckout.com/products/one-time-payments/saved-cards Enable your customers to save cards for faster future payments and manage their saved cards securely with xPay. ## Customer Experience * Merchants can provide a checkbox in their payment flow to let customers choose to save their card. * If checked, pass the `customerId` when creating the payment intent (create a new customer if needed, then use their `customerId`). * On the first successful payment with a `customerId`, the card is saved to the customer’s profile. * On future purchases, customers will see their saved cards as payment options at xPay checkout. (You have to send the `customerId` in the create-intent request to get the saved cards) * Customers can select a saved card to pay instantly, without re-entering card details. * Customers can also manage (delete or use another saved card) from the xPay checkout during any transaction. *** ## Developer Flow API: POST /customer/create
Request: Customer details (name, email, etc.)
Response: Returns a customerId.
API: POST /payment/create-intent
Request: Include the customerId in the payload. Provide payment details (amount, currency, etc.).
Response: Returns an intentId and payment instructions.
If you want the card to be saved for future use, you must pass the customerId in the request. The system will automatically save the card for the customer if the payment is successful and the payment method supports saving.
Customer enters card details and completes payment. The card is securely tokenized and saved to the customer’s profile. On future purchases, customers will see their saved cards as payment options at xPay checkout. (You have to send the customerId in the create-intent request to get the saved cards)
*** ## Summary for Developers * To enable saved cards: Always create a customer and use their customerId in payment requests. * Customers can manage their saved cards directly from the xPay checkout interface. # Payment Links Source: https://docs.xpaycheckout.com/products/payment-links/payment-links Create shareable payment links for one-time and subscription payments with xPay's flexible payment link solution. ## What are Payment Links? Payment Links are standalone web pages that allow customers to make payments through shareable URLs. They provide a complete payment experience without requiring any technical integration, making them ideal for businesses that want to start accepting payments quickly. ## Types of Payment Links

Perfect for individual transactions, one-time payment links are ideal for single purchases and immediate payments.

  • Unique Short URLs - Short URLs for easy sharing
  • Multiple Payment Methods - Support for cards, digital wallets, and more
  • Configurable Expiry - Set custom expiration dates for your links
  • Multi-Use Limits - Control how many times a link can be used
  • Product Page - Display product details and images
  • Email Notifications - Automatic notifications for payment events
#### Link Statuses
  • ACTIVE - Link is available for payment
  • COMPLETED - Payment has been successfully processed
  • EXPIRED - Link has expired or been manually expired

Designed for recurring billing, subscription payment links create ongoing payment relationships with customers.

  • Flexible Billing Cycles - Daily, weekly, monthly, yearly intervals
  • Trial Periods - Support for free trials and promotional periods
  • Upfront Payments - Optional initial charges with subscription setup
  • Multi-Use Limits - Control how many subscriptions can be created
  • Automated Billing - Handles recurring charges automatically
  • Subscription Management - Complete lifecycle management
#### Link Statuses
  • ACTIVE - Link is available for subscription creation
  • COMPLETED - Subscription has been successfully created
  • EXPIRED - Link has expired or been manually expired
## Product Page Enhance your payment links with rich product details to increase conversion rates and provide customers with comprehensive information about what they're purchasing. You can add product details both through the dashboard interface or programmatically via API. ### Add Product Details

Include product information when generating payment links to create more engaging and informative payment pages:

Use the xPay dashboard to easily add product details:

  1. Navigate to the Payment Links section in your dashboard
  2. Click `New Payment Link` or `New Subscription Link`
  3. Enter your amount and currency and click on `Advanced Options`
  4. Click on `Create Product Page` checkbox and fill in the product details including name and description. You can also limit the number of times the link can be used.
  5. Configure other link settings and generate

Add product details programmatically using the productPage object in your API request:

```json theme={null} { "productPage": { "name": "Premium Subscription", "description": "Access to premium features and content" } } ``` ```json theme={null} { "productPage": { "name": "Monthly Membership", "description": "Unlimited access to all premium content and features" } } ```
  • productPage.name (required) - Product name between 2-100 characters
  • productPage.description (optional) - Product description up to 500 characters
## Email Notifications
  • Link Generation - Notify customers when links are created (if email provided)
  • Payment Success - Confirm successful payments to customers
  • Payment Failure - Alert customers about failed payments
  • Subscription Updates - Notify about subscription status changes
  • Merchant Notifications - Real-time updates for all payment events
*** ## Getting Started Ready to create your first payment link? Follow our step-by-step guide:   Generate One-Time Link } href="/developer-resources/endpoints/payment-links/generate-link" />   Generate Subscription Link } href="/developer-resources/endpoints/payment-links/subscription-link" /> # Platform Connect Source: https://docs.xpaycheckout.com/products/platform-connect/overview Onboard and manage sub-merchants under a single platform account. Platform Connect lets you act on behalf of multiple connected merchants from one login, while keeping each merchant's transactions, and settlements isolated. ## What is Platform Connect? Platform Connect is xPay's multi-account solution for marketplaces, software platforms, and aggregators that need to accept payments **on behalf of** other businesses. The setup splits responsibility between two roles:
  • Platform Merchant — the parent account. Onboards Connect merchants, switches into them from the dashboard, and uses one set of API keys to operate across all of its connected accounts. A Platform merchant cannot accept payments itself.
  • Connect Merchant — a regular xPay merchant that lives under a Platform. Accepts payments, owns its own customers, disputes, and settlements. Linked to its parent via platform merchantId.
Platform Connect is enabled per-account by xPay. To turn on the Platform Connect solution for your merchant, reach out to your account manager or [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com). *** ## When to use it Sellers list and transact on your platform. Each seller is a Connect merchant — they get their own payouts and dispute responsibility, while you keep one integration. Your customers run their own businesses on top of your software (booking systems, e-commerce builders, vertical SaaS). Onboard each customer as a Connect merchant so they can accept payments without integrating xPay themselves. You bring xPay to a network of sub-merchants. Manage onboarding, KYB, and operations centrally — payments and settlements still flow merchant-by-merchant. *** ## How it works ```mermaid theme={null} sequenceDiagram autonumber participant PD as Platform Dashboard participant XS as xPay Server participant CM as Connect Merchant rect transparent note over PD,XS: 1. Register a Connect merchant XS-->>PD: { merchantId, merchantName } end rect transparent note over CM,XS: 2. Connect merchant completes onboarding (KYB) CM->>XS: Submit business details / KYC docs XS-->>XS: Internal verification → activated end rect transparent note over PD,XS: 3. Platform acts on behalf of Connect merchant PD->>XS: API call with header x-connect-merchant-id: XS-->>XS: Validate connectMerchantId belongs to Platform XS-->>PD: Response scoped to Connect merchant end ``` From the Platform dashboard - [connect page](https://app.xpaycheckout.com/connect), create a new Connect merchant. The Connect merchant completes the standard xPay onboarding flow (business details, KYC, settlement bank, documents). When approved, both the Connect merchant's owner and the Platform's owner are notified by email. Once activated, the Platform can switch into any of its Connect merchants:
  • Dashboard: use the Connect account dropdown in the header (or the Connect page) to switch context.
  • API: include the header x-connect-merchant-id: \ on any authenticated request.
All read/write operations execute as the Connect merchant.
Drop the x-connect-merchant-id header (or click Switch to Platform account in the dashboard) to return to the Platform context.
*** ## The `x-connect-merchant-id` header This single header is the entire wire-protocol of Platform Connect. It tells xPay: *"I am authenticated as the Platform, but please scope this request to one of my Connect merchants."* | Header | Value | Required when | | ----------------------- | ----------------------------------------------------------------------------- | -------------------------------------- | | `x-connect-merchant-id` | A Connect merchant ID (e.g. `me_abc123…`) owned by the authenticated Platform | Acting on behalf of a Connect merchant | xPay validates on every request that the supplied `connectMerchantId` actually belongs to the calling Platform. Any mismatch returns `403 Forbidden — Connect Merchant Id does not exist`. Idempotency keys are scoped per-merchant. Two requests with the same idempotency key but different x-connect-merchant-id values are treated as independent. *** ## Behavioural rules Any payment-creation API call made directly as a Platform merchant (no x-connect-merchant-id) is rejected with "Platform merchants cannot accept payments". Payments must always be scoped to a Connect merchant. Once activated, a Connect merchant has its own keys, settlements, dispute handling. The Platform link does not affect runtime behaviour — it only governs who can act on behalf of whom. When a Connect merchant is approved, the activation email is sent to the Connect merchant's owner and CC'd to the Platform's owner so the Platform can track onboarding progress. *** ## Dashboard UX
  • Register Connect account — create a new Connect merchant inline. The new merchant is added to the Platform's roster immediately.
  • Switch — jump into any Connect merchant; the dashboard reloads scoped to that merchant.

A persistent dropdown in the dashboard header lets you switch between Connect merchants from anywhere. A pulsing dot indicates that you are currently acting as a Connect merchant; click Switch to Platform account to return.

# Integration Process Source: https://docs.xpaycheckout.com/products/setup-method/integrationProcess Learn how to integrate xPay's Setup Method flow to securely store and charge customer payment methods. ```mermaid theme={null} sequenceDiagram autonumber participant MF as Merchant Frontend participant MS as Merchant Server participant XS as xPay Server participant XC as xPay Checkout rect transparent note over MS,XS: Create a customer first MS->>XS: POST /customers/create { email, ... } XS-->>MS: { customerId } end rect transparent note over MS,XS: Initialize setup method alt Hosted Flow MS->>XS: POST /setup-method/create { customerId, callbackUrl, ... } else Server Side Flow MS->>XS: POST /setup-method/s2s/create { cardDetails, customerId, ... } end XS-->>MS: { setupMethodId, fwdUrl } end rect transparent note over MS,MF: Forward data to browser MS-->>MF: Send fwdUrl and setupMethodId end rect transparent note over MF,XC: Open xPay checkout MF->>XC: Open fwdUrl end rect transparent note over XC,XS: Customer completes setup XS->>MS: Webhook setup_method.success { setupMethodId, pmId } XS-->>MF: Redirect to callbackUrl end rect transparent note over MS,XS: Charge tokenized payment method (later) MS->>XS: POST /charge-tokenised-pm { pmId, customerId, amount, ... } XS-->>MS: { paymentResult } end ``` Before setting up a payment method, you need to create a customer in the xPay system. Make a **create-customer** POST request to xPay's API from the Merchant Server, which returns a `customerId` in the response. See [create-customer API](/developer-resources/endpoints/customer/create-customer) for details. The `customerId` is required for creating a setup method and charging the payment method later. Initialize the setup method using one of the following options: * **Hosted Flow** — Make a **create-setup-method** POST request. xPay handles the payment form UI. See [create-setup-method API](/developer-resources/endpoints/setup-method/create-setup-method) for details. * **Server Side Flow** — Make a **create-s2s-setup-method** POST request with the customer's card details directly from your server. See [create-s2s-setup-method API](/developer-resources/endpoints/setup-method/create-s2s-setup-method) for details. Both return a `setupMethodId` and `fwdUrl` in the response. The **callbackUrl** in the request should be configured to your client-side page responsible for managing the redirect from xPay checkout following the setup process. The Server Side flow requires **PCI DSS compliance**, as it involves handling raw card data on your server. Server Side currently only supports raw card payments. Once the setup method is created, the xPay Server will respond with a `setupMethodId`, which is used to track the setup status throughout the process. The Merchant Server should log or store this identifier for future reference. The Merchant Server forwards the setup method data with `fwdUrl` to the Merchant Frontend, enabling it to manage user interactions related to the payment method setup. Redirect the user to xPay's checkout page to initiate the payment method setup using the `fwdUrl`. ```javascript JavaScript theme={null} const redirectToSetup = () => { const url = new URL(fwdUrl); // fwdUrl received from your server after creating a setup method window.open(url.href).focus(); }; ``` #### Optional checkout parameters Append these query parameters to the `fwdUrl` to change how the checkout page looks. Keep every parameter already in the `fwdUrl` and add these to it. The checkout is currently available in **English and German only**. | Parameter | Values | What it does | | -------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `locale` | `en`, `de` | Opens the checkout in English or German. These are the only supported languages today. Defaults to the language the customer last chose, otherwise English. Any other value falls back to English. | | `hideCloseBtn` | `true`, `false` | `true` hides the checkout's close button. | ```javascript theme={null} const redirectToSetupMethodCheckout = () => { const url = new URL(fwdUrl); url.searchParams.set("locale", "de"); // open the checkout in German url.searchParams.set("hideCloseBtn", "true"); window.location.href = url.toString(); }; ``` `locale` translates the checkout page only. Emails and some payment errors stay in English. * Configure your webhook endpoint to receive the `setup_method.success` event. * When the setup is successful, you'll receive a webhook with the `pmId` (Payment Method ID). * Store this `pmId` securely in your database for future use. Once you have the `pmId`, you can charge the customer's payment method using the **charge-tokenised-pm** POST request. See [charge-tokenised-pm API](/developer-resources/endpoints/setup-method/charge-tokenised-pm) for details. ```javascript JavaScript theme={null} const chargePaymentMethod = async (pmId, customerId, amount, currency) => { const response = await fetch('/payments/charge-tokenised-pm', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pmId, customerId, amount, currency }) }); return await response.json(); }; ``` You can monitor the status of the setup method using the **get-setup-method** GET request. See [get-setup-method API](/developer-resources/endpoints/setup-method/get-setup-method) for details. ```javascript JavaScript theme={null} const getSetupMethodStatus = async (setupMethodId) => { const response = await fetch(`/setup-method/${setupMethodId}`); return await response.json(); }; ``` You can track the status of a payment method token using the **get-payment-method-token** GET request. See [get-payment-method-token API](/developer-resources/endpoints/setup-method/get-payment-method-token) for details. The payment method token can have two statuses: * `LIVE`: The token is active and can be used for transactions * `DELETED`: The token has been deleted and cannot be used for transactions ```javascript JavaScript theme={null} const getPaymentMethodTokenStatus = async (paymentMethodTokenId) => { const response = await fetch(`/payment-method-token/${paymentMethodTokenId}`); return await response.json(); }; ``` It's recommended to check the token status before attempting to charge a payment method to ensure it's still valid. *** By following this process, you can securely store customer payment methods and charge them for future transactions. The setup method flow provides a seamless experience for customers while maintaining security and compliance standards. # Overview Source: https://docs.xpaycheckout.com/products/setup-method/overview Securely collect and store customer payment methods for future use with xPay's Setup Method solution. ## What is Setup Method? Setup Method is designed for businesses that need to securely collect and store customer payment information for future transactions. This solution provides a secure, compliant way to tokenize payment methods while maintaining audit trails and supporting various payment gateways and methods. This feature is disabled by default. To turn it on for your account, please contact your account manager or [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com). ## Setup Method Statuses
  • `CREATED` - Setup method has been initiated
  • `SUCCESS` - Payment method successfully added and tokenized
  • `FAILED` - Setup process failed
  • `CANCELLED` - Setup was cancelled by user or merchant
## Payment Method Token Lifecycle
  • `LIVE` - Token is active and can be used for transactions
  • `DELETED` - Token has been deleted and cannot be used for transactions
It's recommended to check the token status before attempting to charge a payment method to ensure it's still valid. *** ## Getting Started Ready to integrate Setup Method? Follow our step-by-step guide: # Integration Process Source: https://docs.xpaycheckout.com/products/subscription/integrationProcess Learn how to integrate xPay’s subscription payment flow into your website using xPay’s payment gateway APIs. ```mermaid theme={null} sequenceDiagram autonumber participant MF as Merchant Frontend participant MS as Merchant Server participant XS as xPay Server participant XC as xPay Checkout rect transparent note over MF,MS: Customer clicks Subscribe MF->>MS: Create subscription request end rect transparent note over MS,XS: Initialize subscription MS->>XS: POST /subscriptions/create { interval, amount, callbackUrl, ... } XS-->>MS: { subscriptionId, fwdUrl } end rect transparent note over MS,MF: Forward data to browser MS-->>MF: Send fwdUrl and subscriptionId end rect transparent note over MF,XC: Open xPay checkout MF->>XC: Open fwdUrl end rect transparent note over XC,XS: Customer completes checkout XS->>MS: Webhook subscription. { subscriptionId, status } XS-->>MF: Redirect to callbackUrl?subscription_id end rect transparent note over MF,MS: Frontend reads server-confirmed status MF->>MS: GET /subscription-status?subscription_id MS-->>MF: { status: ACTIVE | TRIALING | CREATED } MF-->>MF: Render result page based on status end ``` From your backend, call the **Create Subscription** API to initialize the subscription.\ The response contains `subscriptionId` and `fwdUrl`.\ See [Create Subscription API](/developer-resources/endpoints/subscriptions/create-subscription) for details. Set **callbackUrl** to a client page that can read the redirect parameters and show a result screen. Save the `subscriptionId` along with any correlation IDs.\ This ensures you can reconcile webhook notifications with customer sessions. Store only the minimal customer metadata required to render the post-checkout page. Return the `fwdUrl` and subscription details to the frontend so the customer can start the checkout flow. Ensure the page is ready to handle navigation and the redirect to your **callbackUrl**. Use the `fwdUrl` to redirect customers to xPay’s subscription checkout page. ```javascript theme={null} const redirectToSubscriptionCheckout = () => { const url = new URL(fwdUrl); // fwdUrl received from your server window.open(url.href).focus(); }; ``` #### Optional checkout parameters Append these query parameters to the `fwdUrl` to change how the checkout page looks. Keep every parameter already in the `fwdUrl` and add these to it. The checkout is currently available in **English and German only**. | Parameter | Values | What it does | | -------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `locale` | `en`, `de` | Opens the checkout in English or German. These are the only supported languages today. Defaults to the language the customer last chose, otherwise English. Any other value falls back to English. | | `scfa` | `true`, `false` | `false` hides the convenience fee amount. | | `hideCloseBtn` | `true`, `false` | `true` hides the checkout's close button. | ```javascript theme={null} const redirectToCheckout = () => { const url = new URL(fwdUrl); url.searchParams.set("locale", "de"); // open the checkout in German url.searchParams.set("scfa", "false"); // hide the convenience fee amount url.searchParams.set("hideCloseBtn", "true"); window.location.href = url.toString(); }; ``` `scfa=false` only hides the fee amount. The convenience fee label stays, the fee remains in the total, and the customer is charged the same. It changes what's displayed, nothing else. `locale` translates the checkout page only. Emails and some payment errors stay in English. After checkout, xPay sends a **webhook** to your backend with the final outcome: * [subscription.active](/developer-resources/webhooks/events/subsEvents/active) for successful subscription creation * The webhook payload includes `subscriptionId` and other relevant subscription details. Always treat the webhook as the source of truth.\ Make your webhook handler idempotent and validate the signature. In parallel, the customer is redirected to your **callbackUrl** with `subscription_id` in the query string.\ The frontend should display the result page using the status already received via webhook. ```javascript theme={null} const onSubscriptionPageLoad = async () => { const url = new URL(window.location.href); const subscriptionId = url.searchParams.get("subscription_id"); // Query your own backend which has stored the webhook result const res = await fetch(`/subscription-status?subscription_id=${subscriptionId}`, { credentials: "include" }); const { status } = await res.json(); if (["ACTIVE", "TRIALING"].includes(status)) { // show subscription success UI } else { // show failure UI } }; ``` *** By following this flow, subscription confirmation is handled via **webhooks** on your backend,\ while the redirect ensures a smooth experience for customers. *** # Overview Source: https://docs.xpaycheckout.com/products/subscription/overview Automate recurring billing with xPay's subscription solution designed for businesses with recurring revenue models. ## What is Subscription? Subscription is designed for businesses that need to process recurring payments on a scheduled basis. This solution provides automated billing, flexible payment schedules, and comprehensive subscription management capabilities. One Time Charge on a subscription is disabled by default. To turn it on for your account, please contact your account manager or [hello@xpaycheckout.com](mailto:hello@xpaycheckout.com). ## Billing Cycles
  • Daily - Charge every day
  • Weekly - Charge every week on the same day
  • Monthly - Charge every month on the same date
  • Yearly - Charge annually on the same date
## Retry Mechanism   Payment Recovery } href="/products/subscription/subscription-retry-mechanism">

xPay automatically retries failed payments with intelligent retry logic:

  • Exponential Backoff - Smart retry timing to avoid overwhelming payment methods
  • Maximum Retry Attempts - Prevent infinite retry loops
  • Webhook Notifications - Get notified when all the retries are exhausted
*** ## Getting Started Ready to integrate Subscription? Follow our step-by-step guide: # Retry Mechanism Source: https://docs.xpaycheckout.com/products/subscription/subscription-retry-mechanism Comprehensive system for handling failed subscription payments with automatic and manual retry capabilities. xPay's Subscription Retry Mechanism is a robust system designed to handle failed subscription payments intelligently. It ensures that temporary payment issues don't immediately terminate subscriptions while providing clear escalation paths when payments consistently fail. ## Retry Configuration The retry mechanism operates with predefined rules to ensure optimal payment recovery: * **Automatic Retry Schedule:** 4, 8, 12, and 24 hours after failure. * **Retry Limits:** 4 automatic attempts max, with a 4-hour cooldown between manual retries. ## Manual Retry Capability Merchants can retry failed subscription payments through the xPay dashboard or the [Manual Retry API](/developer-resources/endpoints/subscriptions/manual-retry). Manual retries are only allowed when the subscription is in the `UNPAID` status. Manual retries are subject to a 4-hour cooldown. If a retry is attempted too soon, the API returns the earliest time at which another retry can be attempted. ## Notification System The system sends various notifications during the retry process:
  Customer Notifications
  • First Payment Failure - Immediate notification to customer
  • Final Failure - Customer notification with payment update link
  Merchant Notifications
  • Failed Subscription Transactions - Notifications for failed subscription transactions
## State Management The subscription retry mechanism manages subscription states throughout the retry process:
  • ACTIVE/TRIALING - Normal subscription states that can be charged
  • UNPAID - Final state after all retries are exhausted
  • Next Payment Date - Dynamically updated for retry scheduling
## Webhook Events The retry mechanism triggers specific webhook events to keep your system updated:
  • subscription.cycle\_charged - Successful retry payment
  • subscription.unpaid - All retries exhausted
  • subscription.ended - Subscription terminated after retry failure
  View Webhook Events } href="/developer-resources/webhooks/events/subsEvents" />   Webhook Setup } href="/developer-resources/webhooks/introduction" /> *** # Subscription Statuses Source: https://docs.xpaycheckout.com/products/subscription/subscription-statuses Below are the various subscription statuses that you may encounter when managing subscriptions on the xPay platform: | **Status** | **Description** | | ----------- | ----------------------------------------------------------------------------------------------------------- | | `CREATED` | The subscription has been created, but the first payment has not yet been processed. | | `TRIALING` | The subscription is currently in its trial period before transitioning to an active state. | | `ACTIVE` | The subscription is currently active and recurring payments are being processed as per the schedule. | | `PAUSED` | The subscription has been paused by the merchant. No payments will be processed until it is resumed. | | `UNPAID` | The subscription has entered an unpaid state due to one or more failed payment attempts. | | `ENDED` | The subscription has ended either due to cancellation, completion of all billing cycles, or expiration. | | `CANCELLED` | The subscription has been cancelled by the merchant or customer, and no further payments will be processed. | *** These statuses help in tracking the lifecycle of a subscription from creation to completion, including trial periods, non-payment issues, and cancellations. Now, you can explore [subscription endpoints](/developer-resources/endpoints/subscriptions/create-subscription) to integrate your subscription. # Virtual Bank Accounts Source: https://docs.xpaycheckout.com/products/virtual-bank-accounts/virtual-bank-accounts Digital bank accounts that provide businesses with real bank account details without traditional banking setup. ## What are Virtual Bank Accounts? Virtual Bank Accounts are digital representations of real bank accounts that provide businesses with actual bank routing and account numbers. They enable businesses to receive payments, track transactions, and manage their financial operations through a streamlined digital interface. ## Account Details Each Virtual Bank Account provides comprehensive banking information:
  Account Information
  • Account Number - A real bank account number
  • Routing Information:
    • Domestic Fast Credit (ACH)
    • Domestic Wire
    • Global Wire (SWIFT)
  • Currency - USD
## Transaction Management The system tracks all VBA transactions including:
  • Deposit amounts - Track all incoming payments to the VBA
  • Statement descriptors - Clear descriptions that appear on bank statements
## Balance Tracking Merchants can check their VBA balance in real-time through the dashboard. #### Balance Features
  • Real-time balance tracking
  • Balance monitoring through dashboard
*** VBAs essentially provide the functionality of a real bank account through a digital interface, making it easier for businesses to manage their financial operations without the complexity of traditional banking relationships. # Team Roles & Permissions Source: https://docs.xpaycheckout.com/untitled-page What each permission on the Manage Team page controls, and what the default roles can do. Roles decide what each teammate can do in the dashboard. Every teammate has one role. Manage your team and their permissions in the dashboard. ## Default roles Every account starts with three roles. | Permission | Owner | Admin | Sales | | -------------------------------- | :---: | :---: | :---: | | Transactions: Create | ✅ | ✅ | ✅ | | Transactions: Refund & Cancel | ✅ | ✅ | — | | Transactions: Dispute Management | ✅ | ✅ | — | | Transactions: Receive Mail | ✅ | ✅ | — | | Balances: View | ✅ | ✅ | — | | Virtual Bank Account: View | ✅ | ✅ | — | | Settings: Manage | ✅ | ✅ | — | | Team management: Manage | ✅ | — | — | | Developer: Manage | ✅ | ✅ | — | | Onboarding: Manage | ✅ | — | — | * **Owner** — full access. Can't be edited. * **Admin** — everything except team and onboarding. * **Sales** — payment links only. Every teammate can view transactions and Merchant Details, whatever their role. ## Creating a new role Need something in between? Create a role with exactly the permissions you want. Go to [Settings › Manage Team](https://app.xpaycheckout.com/settings). Name the role. The name can't be changed later. Everything starts off. Tick only what the role needs. Assign the role to teammates from the team list below the table. You can also edit Admin, Sales and your own roles with **Edit**. Owner can't be changed, and roles can't be renamed or deleted. Anyone with an edited role has to sign in again. ## What each permission means ### Transactions | Permission | What turning it on means | | ---------------------- | ---------------------------------------------------------------------------------------- | | **Create** | Create, expire, capture and void payment links. | | **Refund & Cancel** | Refund payments in full or in part, and manage subscriptions. | | **Dispute Management** | Open the Disputes page and respond to chargebacks. | | **Receive Mail** | Receive email alerts about payments, refunds, payouts and disputes. No dashboard access. | Teammates also pick which emails they want under **Profile › Email Preferences**. New teammates start with only dispute emails on. Customer emails, such as receipts, are set in **Settings › Customer Communication**. ### Account & funds | Permission | What turning it on means | | ------------------------------ | ----------------------------------------------------------------------- | | **Balances: View** | View balances, payouts and statements, and download exports. Read-only. | | **Virtual Bank Account: View** | View your account details, balance and incoming transfers. Read-only. | ### Administration | Permission | What turning it on means | | --------------------------- | ----------------------------------------------------------- | | **Settings: Manage** | Edit Customer Communication, Payment Methods and your logo. | | **Team management: Manage** | Invite teammates and manage roles. Treat as full access. | | **Developer: Manage** | View and create API keys, and manage webhooks. | | **Onboarding: Manage** | Complete business verification (KYB) and upload documents. |