# Orchestra Solutions - Complete Documentation > This file contains the full content of all Orchestra Solutions developer documentation pages. > For a lightweight index version, see llms.txt. > Source: https://developers.orchestrasolutions.com --- # Orchestra Solutions Documentation URL: https://developers.orchestrasolutions.com/index --- **New to payment orchestration?** Read [Introduction to Payment Orchestration](https://developers.orchestrasolutions.com/p18n-the-orchestra-way) to understand how Orchestra works and whether it's right for your integration. **Ready to start building?** Follow the [Quickstart](https://developers.orchestrasolutions.com/quickstart) to make your first API call in under 5 minutes. ## Two Ways to Integrate JavaScript library with pre-built UI. Handles card entry, Google Pay, Apple Pay, and other APMs. Best for rapid deployment and staying out of PCI scope. Direct HTTP calls from your backend. Full control over UI and payment flow. Best when you have existing payment infrastructure or need maximum flexibility. Not sure which to choose? See the [detailed comparison](https://developers.orchestrasolutions.com/concepts/api-vs-library). ## What You Can Do Accept cards, digital wallets, PayPal, and bank transfers. Authorize, capture, void, and refund through connected providers. Securely tokenize cards and digital wallets for repeat transactions without re-entering details. Direct transactions to specific providers based on your business logic. Configure backup providers to handle transactions when your primary fails. ## How It Works 1. **Connect your payment providers** - Add credentials for Stripe, Adyen, Worldpay, or any of our [{supportedIntegrations} supported gateways](https://orchestrasolutions.com/integrations/) 2. **Make API calls to Orchestra** - Use a single, consistent API for all payment operations 3. **Orchestra routes to your providers** - Transactions go to the gateway you specify (or failover to backups) Need a payment gateway or method we don't support? [Request an integration](https://orchestrasolutions.com/integration-request/) - we add new providers at no cost. ## Quick Links Understand what Orchestra does and how it works Make your first charge in 5 minutes Full endpoint documentation Support channels and community --- # Introduction to Payment Orchestration URL: https://developers.orchestrasolutions.com/p18n-the-orchestra-way --- ## Start at the End Your customer sees a payment form. They enter their card. They click "Pay." They see a confirmation. That's it. That's what you're building toward. Everything else is infrastructure to make that moment happen reliably, securely, and at scale. ![Payment form](https://developers.orchestrasolutions.com/images/payment-form-horizontal.png) ## Key Terms Before we go further, let's define a few concepts you'll see throughout these docs: | Term | What it means | |------|---------------| | **Payment gateway** | Service that processes card transactions (Stripe, Adyen, Worldpay, etc.). You need an account with at least one. | | **Merchant account** | Your account with a payment gateway that lets you accept payments and receive funds. | | **Token** | A reference to stored card details. You use tokens instead of raw card numbers for security. Cards can be tokenized with Orchestra (gateway-agnostic) or with the payment gateway directly (gateway-specific). | | **PCI DSS** | Security standard for handling card data. More card data you touch = more compliance burden. | ## The Form: Build or Borrow? When it comes to building that payment form, Orchestra gives you two paths, each with different tradeoffs: | Approach | What You Get | What You Handle | Payment Methods | |----------|--------------|-----------------|-----------------| | **1. Payments Library** | Pre-built UI, hosted card entry, PCI handled | Styling, callback handling | Cards + APMs (Apple Pay, Google Pay, PayPal, UPI and more) | | **2. REST API** | Full control over UI and flow | Building the form, tokenization flow | Cards only | **What you'll actually build:** **If you choose the Payments Library:** You embed our JavaScript. When the user clicks "Pay," a popup overlay appears over your page (your site grays out behind it). They enter card details in that popup. You receive the payment result and, optionally (if selected), a token for the card in a callback. You can store the card with Orchestra or with the payment gateway directly. Card data never touches your servers. ![Payments Library popup flow](https://developers.orchestrasolutions.com/images/payment-popup-flow.png) **If you choose the REST API:** You build your own form. You collect card details, send them to Orchestra's tokenization endpoint, receive a token. Then you use that token to charge. Card data passes through your server briefly once (or you use a third-party vault to avoid this entirely). ![REST API flow](https://developers.orchestrasolutions.com/images/rest-api-flow.png) **How to choose between them:** **Choose Payments Library if:** - You want the fastest path to production with minimal PCI compliance burden - You need to support alternative payment methods (Apple Pay, Google Pay, PayPal, UPI) - Pre-built UI components work for your use case **Choose REST API if:** - You need pixel-perfect brand control over every aspect of the payment experience - You're already using a token vault provider - You need to integrate payments into mobile apps or custom flows Either way, both approaches use the same backend processing, so you're getting the same reliability and feature set. Both paths allow you to charge immediately, or store the token to charge later (subscriptions, saved payment methods, one-click checkout). **Compare in detail:** [API vs Library](https://developers.orchestrasolutions.com/concepts/api-vs-library) **Your foundational choice:** Library vs API determines your PCI compliance path, development timeline, and UI control. Everything else we cover works with either approach. ## What Payment Methods Can You Accept? Beyond traditional card payments, the Payments Library gives you access to multiple payment methods that your customers might prefer: | Payment Method | Geographic Coverage | Notes | |----------------|---------------------|-------| | Cards (Visa, Mastercard, Amex, etc.) | Global | Via any configured gateway | | Google Pay | 70+ countries | Pre-built UI included | | Apple Pay | 70+ countries | Pre-built UI included | | PayPal | 200+ countries | Pre-built UI included | | UPI | India | Pre-built UI included | | Bank transfers | Select markets | Regional availability varies | One of the benefits of this approach is consistency: the same callback receives results regardless of which payment method your customer chooses. Your integration code stays the same whether they paid with a Visa card, Apple Pay, or PayPal. Need a payment method we don't support yet? We can add new payment methods at no cost to you. Contact us to discuss your requirements and timeline. ## Behind the Form: What Actually Happens When the customer clicks "Pay": ![Payment routing flow](https://developers.orchestrasolutions.com/images/payment-routing-flow.png) See all [{supportedIntegrations} supported gateways](https://orchestrasolutions.com/integrations/). **Here's the key insight:** Orchestra sits between your application and your payment gateways. You talk to one API, and Orchestra handles the translation to each gateway's specific requirements. This means you send the same request format regardless of which gateway you're using, and you get back normalized responses that look the same whether the payment went through Stripe, Adyen, or any other provider. **The orchestration advantage:** This unified API is why you can switch from Stripe to Adyen by changing one parameter instead of rewriting your integration. The same request format works across all {supportedIntegrations} supported providers. ## The Payment Lifecycle When you're ready to collect money from a customer, you have two approaches to choose from, depending on your business needs: **1. Charge (and optionally tokenize)** - This is the straightforward approach: authorize and capture (an optionally tokenize) in one step, and money moves immediately. You'll use this when you can fulfill the order right away, like with digital goods, subscription signups, or in-person purchases. **2. Authorize → Capture** - This two-step approach lets you reserve funds now and collect later. It's perfect for situations where you need some time before fulfilling the order, like shipping physical goods, hotel check-outs where the final amount might vary, or any scenario where you want to hold funds before finalizing the charge. ![Charge vs Authorize + Capture](https://developers.orchestrasolutions.com/images/charge-vs-authorize-flow.png) Both operations work identically across all your gateways. You can also **void** (cancel an authorization before capture) or **refund** (return funds after capture). ## Why Multiple Gateways? Here's an important point upfront: if you're only using one payment gateway, you should integrate with them directly. Stripe's API is excellent, Adyen's dashboard is powerful, and direct integrations are often the right choice when you only need one provider. We're not trying to compete with single-gateway integrations. Orchestra becomes valuable when your business needs multiple gateways working together: | Reason | Example | |--------|---------| | **Failover** | Primary gateway down? Route to backup automatically. | | **Geographic coverage** | Adyen for EU, local processor for Brazil, different provider for APAC. | | **Payment methods** | Gateway A for cards, Gateway B for bank transfers, PayPal for wallets. | | **Cost optimization** | Route Visa to cheaper processor, Amex to the one with better rates. | | **Partner requirements** | Your merchants have existing processor relationships you need to support. | | **Avoiding lock-in** | Add/remove gateways without rewriting integration code. | | **Future growth** | Need a new gateway next year? Add credentials, update routing logic. Your integration code doesn't change. [See all 90+ supported gateways](https://orchestrasolutions.com/integrations/). If we don't support it yet, we'll add it (2-4 weeks, no cost to you). | **The orchestration value:** One integration that speaks to all of them. ![Without Orchestration vs With Orchestration](https://developers.orchestrasolutions.com/images/orchestration-comparison.png) **Decision checkpoint:** If you recognize your business in this table, Orchestra can help. If you only need one gateway and don't anticipate adding more, integrate directly with that provider - their APIs are excellent and you'll avoid the orchestration layer. ## Challenges Orchestra Helps You Overcome Here's where multi-gateway payment integration gets complicated - and how Orchestra helps: --- **Challenge: Gateway goes down, you lose sales** When your payment gateway has an outage, every transaction fails and you lose sales. Orchestra helps you build resilience by supporting automatic sequential failover: ```javascript // Orchestra tries each in order until one succeeds await charge({ amount: 49.99, currency: 'USD', card: cardToken, paymentGatewayAccountNames: ['stripe-primary', 'adyen-backup', 'worldpay-emergency'] }); ``` You can also implement your own custom failover logic based on specific error conditions. Because Orchestra's API is unified across all providers, this kind of intelligent routing is straightforward to build: ```javascript async function chargeWithSmartFailover(payment) { try { return await charge({ ...payment, paymentGatewayAccountName: 'stripe-primary' }); } catch (error) { if (error.code === 'RATE_LIMIT') { return await charge({ ...payment, paymentGatewayAccountName: 'adyen-high-volume' }); } if (error.code === 'CURRENCY_NOT_SUPPORTED') { return await charge({ ...payment, paymentGatewayAccountName: 'worldpay-multi-currency' }); } throw error; } } ``` --- **Challenge: Storing cards securely (PCI DSS compliance)** Handling raw card numbers puts you in PCI DSS scope (the security standard governing how businesses handle cardholder data). Options: | Approach | How | PCI Impact | |----------|-----|------------| | **Full Outsourcing** | Card entry happens in Orchestra's hosted card forms. Process a charge, or tokenize the card for later use, directly from the card form. Card data never touches your servers. | SAQ-A eligible if you're a merchant, SAQ-D if you're a service provider* | | **Token Vault** | Receive or collect card details independently and store them with Orchestra. You receive a token to use for future charges. | Card data transits your server only once for a short time frame | | **Third-Party Vault Enhancement** | Use cards stored with a third-party token vault to process charges through your selected PSP. Card never reaches your system. | SAQ-A eligible if you're a merchant, SAQ-D if you're a service provider* | *We can provide guidance prepared by our auditors on how to fill out the SAQ-D for service providers when using Orchestra. The less card data you handle, the simpler your compliance. Full Outsourcing (via the Payments Library) is the easiest path. --- **Challenge: You want routing control, not a black box** Some payment orchestrators make routing decisions for you using their own rules engine. That's not how Orchestra works, and we consider this a competitive advantage. When you use someone else's routing rule engine, you're constrained by the types of rules and logic that they thought of. That might cover most cases, but who's to say your business fits that category? With Orchestra, you set up your own rules based on your own logic and criteria. You're not limited by someone else's assumptions about how routing should work - you have complete flexibility to implement exactly what your business needs. ```javascript function selectGateway(transaction) { // Your business logic, your criteria, your data if (transaction.cardCountry === 'EU') return 'adyen-eu'; if (transaction.region === 'LATAM') return 'local-processor-brazil'; if (transaction.amount > 10000) return 'stripe-high-value'; return 'primary-gateway'; } await charge({ ...payment, paymentGatewayAccountName: selectGateway(transaction) }); ``` **The tradeoff to understand:** This approach means you're responsible for writing and maintaining the routing logic. If you're looking for drag-and-drop rules configuration in a graphical interface, Orchestra isn't the right fit. We've chosen to provide flexibility and control over prescriptive automation, because we believe developers should own their business logic. --- **Why these patterns work:** Orchestra normalizes the differences between gateways. The failover code you write for Stripe/Adyen works identically for any provider pair - same error codes, same response format, same authentication. ## The Infrastructure You'll Need Before you can start processing payments through Orchestra, you'll need to set up a few pieces of infrastructure: 1. **Payment gateway accounts** - You'll need relationships with actual payment gateways like Stripe, Adyen, Worldpay, or others to process payments. Orchestra routes transactions to these providers, but doesn't replace them. 2. **Gateway credentials stored in Orchestra** - Once you have accounts with your chosen processors, you'll store each processor's API keys with Orchestra. This lets you reference them by name in your API requests rather than managing credentials in your own code. 3. **Orchestra API key** - Finally, you'll need an API key from Orchestra to authenticate your requests to our platform. **Want to test immediately?** Orchestra provides mock payment gateways (NULLSuccess/NULLFailure) that require no external accounts. See the [Quickstart](https://developers.orchestrasolutions.com/quickstart) to start testing in 5 minutes. ```javascript // Same code structure, different provider await charge({ amount: 49.99, currency: 'USD', card: cardToken, paymentGatewayAccountName: 'stripe-eu' }); await charge({ amount: 49.99, currency: 'USD', card: cardToken, paymentGatewayAccountName: 'adyen-us' }); await charge({ amount: 49.99, currency: 'USD', card: cardToken, paymentGatewayAccountName: 'worldpay-apac' }); ``` Orchestra uses major currency units (49.99), not minor units/cents (4999). If your payment gateway works in minor units, Orchestra converts automatically from major to minor units - keeping your requests to Orchestra consistent across all payment gateways. **Where does `cardToken` come from?** - **1. Payments Library:** The hosted popup returns it in your callback after the customer enters their card - **2. REST API:** You send card details to the `/tokenize` endpoint, receive a token back Once you have a token, you never handle raw card numbers again. Tokens are gateway-agnostic. The same token works across all your configured gateways. **Saving Cards for Future Charges** Many businesses need to charge customers multiple times without asking for card details again. This comes up in scenarios like subscriptions, repeat customers, or one-click checkout experiences. When a customer enters their card for the first time (whether through the Payments Library or REST API), you can store it with Orchestra and receive a token back. You save that token in your database linked to the customer, and then use it for all future charges. Your customer never has to re-enter their card details. ![Token storage and reuse](https://developers.orchestrasolutions.com/images/tokenization-flow.png) The token is yours to keep. If you later add a new gateway or switch providers, the same tokens still work. No need to ask customers to re-enter their cards. ## What Orchestra Doesn't Do To set clear expectations, here's what Orchestra isn't designed to do: - **Generally not a payment processor** - Orchestra typically doesn't process payments itself. You'll need merchant accounts with payment processors, and Orchestra routes transactions to them on your behalf. However, we can provide payment processing services through agreements with our US and EU partners where that makes sense for your integration. - **Not a single-gateway replacement** - If you only need one payment gateway like Stripe, you should use Stripe directly. Orchestra adds value when you need to work with multiple providers. - **Not a fraud engine** - For fraud detection and prevention, you'll want to use your payment gateways' built-in fraud tools or dedicated fraud prevention services. Orchestra passes through fraud-related data but doesn't make fraud decisions. However, we can integrate with external fraud services on demand. - **Not a reconciliation system** - While Orchestra returns transaction references that you can use for reconciliation, the actual reconciliation of funds happens in your payment processor dashboards. However, we can add reconciliation capabilities on demand. - **Not a rules engine** - Orchestra doesn't provide a drag-and-drop UI for configuring routing rules. Your routing logic lives in your application code, where you have full control and flexibility. **Clear boundaries:** Orchestra is primarily a routing and translation layer between your application and payment processors. You typically need your own processor accounts, fraud tools, and reconciliation systems. We handle the integration complexity, though we can also provide payment processing services through partnerships where appropriate. ## Ready to Build? At this point, you should have a solid understanding of how payment orchestration works and how Orchestra implements it. You've learned about the customer experience you're building toward, the two integration approaches available to you, how payment operations flow, and the infrastructure you'll need to get started. You also understand when Orchestra makes sense (multiple gateways) and when it doesn't (single gateway), along with the key challenges it helps you overcome around failover, PCI compliance, and routing control. **Ready for your next step?** Let's build a working charge in 5 minutes. First API call in 5 minutes --- # Quickstart URL: https://developers.orchestrasolutions.com/quickstart --- This guide walks you through creating a sandbox account, setting up mock payment gateways, and making your first test charge. No external payment provider accounts required. This quickstart uses Orchestra's built-in mock payment gateways for immediate testing. When you're ready for production, see [Add a Payment Provider](https://developers.orchestrasolutions.com/getting-started/add-payment-provider). ## Setup Sign up at [portal.orchestrasolutions.com](https://portal.orchestrasolutions.com). Create an API key to authenticate your requests: 1. Go to **[API Keys > Create](https://portal.orchestrasolutions.com/#/apikey/create)** 3. Enter a **Name** for the key (e.g., "Development") 4. Ignore the **User** setting for now - when you're ready, see [Managing Users and Permissions](https://developers.orchestrasolutions.com/getting-started/create-account#managing-users) 5. Click **Save** 6. **Copy the key immediately** - you won't see it again Copy the key now - you won't be able to view it again. Mock PSPs are test gateways that return predictable success or failure responses regardless of input. They let you test both code paths without external payment provider accounts. See the Mock Payment Gateways guide for details on limitations and capabilities. Set up test gateways in the Portal: **Success Gateway:** 1. Go to **Resources** > **Payment Gateway Account** > **Create** 2. **Name**: `testSuccess` 3. **Gateway**: `NULLSuccess` 5. Click **Save** **Failure Gateway (for testing):** - **Name**: `testFailure` - **Gateway**: `NULLFailure` ## Choose Your Approach: Payments Library or REST API **Use when:** Customers enter cards in your frontend. Pre-built UI, reduced PCI scope, supports digital wallets (Apple Pay, Google Pay). **Demonstrates:** - Session creation - Frontend integration with payment buttons - Result validation **Use when:** You collect card details on your backend. Full control, mobile apps, recurring payments, custom flows. **Demonstrates:** - Basic charges - Tokenization for PCI scope reduction ### 1. Create eWallet Account Create an eWallet Account in the Portal: 1. Go to **Resources** > **eWallet Accounts** > **Add Account** 2. Name it `testWallet` 3. Select the eWallet Type to be "CardPay" 4. Set Merchant Identifier to be [your_company_name].com.orchestrasolutions 5. Set Merchant Display Name to be your company name 6. Disregard for now all other fields - when you're ready to set up real use case processes, see [Creating eWallet Accounts](https://developers.orchestrasolutions.com/getting-started/create-ewallet-account) 7. Click **Save** ### 2. Install Library ```bash npm install @orchestrasolutions/ewallet ``` ### 3. Create Session (Backend) ```bash curl --location 'https://api.orchestrasolutions.com/EWalletOperations' \ --header 'X-Api-Key: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "operation": "CHARGE", "PaymentGatewayAccountId": "testSuccess", "AllowedeWalletAccountIds": ["testWallet"], "mode": "TEST", "CurrencyCode": "USD", "CountryCode": "US", "Amount": "2.56", "AllowedBrands": ["VISA", "MASTERCARD"] }' ``` ### 4. Display Payment Button (Frontend) ```html ``` ```javascript import * as eWallet from '@orchestrasolutions/ewallet'; // Initialize with JWT from backend const engine = new eWallet.Engine(jwt); // Check available payment methods const available = await engine.checkAvailability(); // Display card payment button engine.payBy( [{ name: 'CardPay', domEntitySelector: '#card-button' }], handleResult, undefined ); function handleResult(result) { if (result.status === 'SUCCESS') { const [data] = engine.parseResultToken(result.token); console.log('Payment successful:', data); // Send result.token to backend for validation } } ``` This is where credit card details are submitted on the frontend. The Payments Library handles card collection and tokenization, keeping sensitive data out of your backend code. ### 5. Validate Result (Backend) - Optional Validate the result token received from Orchestra on the client side and passed to your server. This ensures the token wasn't altered between the client and server. ```bash curl --location 'https://api.orchestrasolutions.com/EWalletOperations/validate' \ --header 'X-Api-Key: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "token": "RESULT_TOKEN_FROM_FRONTEND" }' ``` --- ## 🎉 You're In! You just completed an Orchestra integration using the Payments Library with mock PSPs. These examples demonstrate Orchestra's key capabilities without requiring external payment provider accounts. **Ready for production?** See [Add a Payment Provider](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) to configure real gateways. Your code stays the same - just swap the gateway account names. ### What's Next Full server + client code you can clone and run Full configuration and customization CardPay, ApplePay, GooglePay, PayPal, and more Configure Stripe, Adyen, and more This example assumes you have access to the cards you will be charging. We're using a credit card test number below. ### 1. Basic Charge ```bash cURL curl --location 'https://api.orchestrasolutions.com/PaymentGateway/charge' \ --header 'X-Api-Key: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "paymentGatewayAccountName": "testSuccess", "amount": 2.56, "currency": "USD", "myRef": "PaymentX11235", "card": { "cardType": "Visa", "cardHolderName": "Testing Tester", "cardNumber": "4242424242424242", "expirationYear": 2025, "expirationMonth": 12, "cvv": "123" } }' ``` ```javascript Node.js const response = await fetch( 'https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ paymentGatewayAccountName: 'testSuccess', amount: 2.56, currency: 'USD', myRef: 'PaymentX11235', card: { cardType: 'Visa', cardHolderName: 'Testing Tester', cardNumber: '4242424242424242', expirationYear: 2025, expirationMonth: 12, cvv: '123' } }) } ); const result = await response.json(); console.log(result); ``` ```python Python import requests response = requests.post( 'https://api.orchestrasolutions.com/PaymentGateway/charge', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'paymentGatewayAccountName': 'testSuccess', 'amount': 2.56, 'currency': 'USD', 'myRef': 'PaymentX11235', 'card': { 'cardType': 'Visa', 'cardHolderName': 'Testing Tester', 'cardNumber': '4242424242424242', 'expirationYear': 2025, 'expirationMonth': 12, 'cvv': '123' } } ) print(response.json()) ``` ### 2. Expected Response ```json { "authorizationCode": "fbbb8b", "currency": "USD", "amount": 2.56, "operationType": "Charge", "operationResultCode": "Success", "operationResultDescription": "Successful operation", "gatewayName": "NULLSuccess", "gatewayReference": "b362db", "gatewayResultCode": "OK", "gatewayResultDescription": "Gateway says: Successful operation", "gatewayResultSubCode": null, "gatewayResultSubDescription": null } ``` --- ## 🎉 You're In! You just completed an Orchestra REST API integration using mock PSPs. These examples demonstrate Orchestra's key capabilities without requiring external payment provider accounts. **Ready for production?** See [Add a Payment Provider](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) to configure real gateways. Your code stays the same - just swap the gateway account names. ### What's Next Automatic failover across providers Hold funds and capture later Reverse transactions Configure Stripe, Adyen, and more --- # How Do I...? URL: https://developers.orchestrasolutions.com/how-to --- Can't find what you're looking for? [Ask in our support forum](https://github.com/orchestra-solutions/p18n/discussions). ## Process Payments | I want to... | Go here | |--------------|---------| | Charge a card immediately | [Charge Payments](https://developers.orchestrasolutions.com/guides/rest-api/charge) | | Hold funds and capture later | [Authorize & Capture](https://developers.orchestrasolutions.com/guides/rest-api/authorize-capture) | | Accept Apple Pay | [Apple Pay](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/apple-pay) | | Accept Google Pay | [Google Pay](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/google-pay) | | Accept PayPal | [PayPal](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/paypal) | | Accept bank transfers | [Bank Pay](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/bank-pay) | | Use multiple payment providers for failover | [Multi-Gateway Failover](https://developers.orchestrasolutions.com/guides/rest-api/multi-gateway-failover) | ## Manage Transactions | I want to... | Go here | |--------------|---------| | Refund a customer | [Refunds & Voids](https://developers.orchestrasolutions.com/guides/rest-api/refunds-voids) | | Cancel an authorization before capture | [Refunds & Voids](https://developers.orchestrasolutions.com/guides/rest-api/refunds-voids) | | Check if a payment succeeded | [Transaction Status](https://developers.orchestrasolutions.com/guides/rest-api/transaction-status) | ## Store Sensitive Data | I want to... | Go here | |--------------|---------| | Tokenize card numbers or other sensitive strings | [Tokenization](https://developers.orchestrasolutions.com/guides/rest-api/tokenization) | | Create tokens for recurring billing | [Gateway Tokenization](https://developers.orchestrasolutions.com/guides/rest-api/gateway-tokenization) | ## Set Up Accounts | I want to... | Go here | |--------------|---------| | Create an Orchestra account | [Create Account](https://developers.orchestrasolutions.com/getting-started/create-account) | | Get an API key | [Generate API Key](https://developers.orchestrasolutions.com/getting-started/generate-api-key) | | Add a payment provider (PSP) | [Add Payment Provider](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) | | Set up Apple Pay credentials | [Apple Pay Setup](https://developers.orchestrasolutions.com/guides/library/applepay-setup) | | Set up Google Pay credentials | [Google Pay Setup](https://developers.orchestrasolutions.com/guides/library/googlepay-setup) | | Set up PayPal credentials | [PayPal Setup](https://developers.orchestrasolutions.com/guides/library/paypal-setup) | ## Test & Go Live | I want to... | Go here | |--------------|---------| | Test without a real PSP account | [Mock PSPs](https://developers.orchestrasolutions.com/guides/utilities/mock-psps) | | Understand sandbox vs production | [Testing & Going Live](https://developers.orchestrasolutions.com/concepts/testing-and-going-live) | | Validate my API key is working | [Validate API Key](https://developers.orchestrasolutions.com/guides/rest-api/utilities/validate-api-key) | | See which gateways Orchestra supports | [List Gateways](https://developers.orchestrasolutions.com/guides/rest-api/utilities/list-gateways) | ## Integrate | I want to... | Go here | |--------------|---------| | Choose between REST API and Payments Library | [API vs Library](https://developers.orchestrasolutions.com/concepts/api-vs-library) | | Use the JavaScript Payments Library | [Library Setup](https://developers.orchestrasolutions.com/guides/library/setup) | | Use the REST API directly | [Charge Payments](https://developers.orchestrasolutions.com/guides/rest-api/charge) | | See a complete working example | [Complete Example](https://developers.orchestrasolutions.com/guides/library/complete-example) | | Handle payment results | [Result Handling](https://developers.orchestrasolutions.com/guides/library/result-handling) | ## Handle 3D Secure | I want to... | Go here | |--------------|---------| | Implement 3DS with the Payments Library | [Library 3D Secure](https://developers.orchestrasolutions.com/guides/library/3d-secure) | | Pass 3DS data via REST API | [REST API 3D Secure](https://developers.orchestrasolutions.com/guides/rest-api/3d-secure) | --- # Creating & Managing an Account URL: https://developers.orchestrasolutions.com/getting-started/create-account --- Orchestra provides a sandbox environment for testing your integration before going live. All sandbox transactions are simulated. No real money moves. ## Sign Up Go to the [registration page](https://portal.orchestrasolutions.com/#/register) and enter your details: | Field | Description | |-------|-------------| | **Name** | Your full name | | **Username** | A unique username for your account | | **Email** | Your email address (used for activation and notifications) | | **Is Sandbox** | Leave checked for a test/sandbox account | Click **Sign Up**. You'll see a confirmation message and receive an activation email. Click the link in the email to continue. The activation link takes you to a page where you'll set your password (8-16 characters). Enter your password and click **Activate User**. After activation, you're automatically logged in and ready to use the Orchestra portal. Sandbox accounts have full API access but only process test transactions. When you're ready for production, contact us to upgrade your account. ## The Portal The Orchestra portal is where you: - Add and manage payment provider connections - Generate and revoke API keys - View transaction logs - Configure failover rules Sandbox accounts have full API access. The only difference from production is that transactions are simulated through your providers' test modes. ## Managing Users Account Admins can add and manage users within their organization. ### Adding a User 1. Go to **[Users](https://portal.orchestrasolutions.com/#/users)** in the portal navigation 2. Click **Create** 3. Fill in the user details: | Field | Description | |-------|-------------| | **Name** | User's full name | | **Email** | Email address (receives activation link) | | **Username** | Unique username for the account | | **Roles** | Assign one or more roles (see [Managing Permissions](#managing-permissions)) | 4. Click **Create** The new user receives an activation email to set their password. ### User Actions From the Users list, you can perform these actions: | Action | When Available | Description | |--------|----------------|-------------| | **Suspend** | Active users | Temporarily disable access | | **Resume** | Suspended users | Restore access | | **Resend Invitation** | Pending users | Send another activation email | | **Unlock** | Locked users | Unlock after failed login attempts | | **Edit** | All users | Update name, email, or roles | | **Delete** | All users | Permanently remove the user | ## Managing Permissions Orchestra uses role-based access control with three permission levels: | Role | Description | |------|-------------| | **SystemAdmin** | Full access to all features and settings | | **AccountAdmin** | Can manage users, roles, and resources within the account | | **RegularUser** | Can use assigned resources but cannot manage users or roles | Only SystemAdmin and AccountAdmin users can assign roles to other users. RegularUsers can view their own roles but cannot modify them. ## Next Steps Connect your first gateway Get credentials for API access --- # Generating API Keys URL: https://developers.orchestrasolutions.com/getting-started/generate-api-key --- Every request to the Orchestra API requires authentication via an API key. This page explains how to create, manage, and secure your API keys. ## Create an API Key In the Orchestra portal, go to **[API Keys](https://portal.orchestrasolutions.com/#/apikey/create)**. Click **Create** to generate a new key. | Field | Description | |-------|-------------| | **Name** | A descriptive label (e.g., "Production Server", "Development", "CI/CD") | | **Assign it to my user** | Check this to assign the key to your own user account | | **Username** | Or select a different user from the dropdown to assign the key to them | You can ignore the user settings entirely. If no user is selected, the API key is automatically assigned to your current user. Click **Save**. Your new API key will be displayed in a popup dialog. **Copy the key immediately and save it securely.** Once you close the popup, you cannot view the API key again. If you lose it, you'll need to create a new one. ## Using Your API Key Include the API key in the `X-Api-Key` header of every request: ```bash curl -X POST https://api.orchestrasolutions.com/PaymentGateway/charge \ -H "Content-Type: application/json" \ -H "X-Api-Key: your_api_key_here" \ -d '{ ... }' ``` ## User Assignment When you assign an API key to a specific user: - The key can only access Payment Gateway Accounts assigned to that user - Transactions are logged under that user's activity - Useful for multi-tenant setups or restricting access If you don't assign a user, the key has access to all Payment Gateway Accounts in your organization. ## Security Best Practices API keys should only exist on your server. Never include them in frontend JavaScript, mobile apps, or public repositories. Store keys in environment variables, not in code. Use secrets managers in production. Create new keys and deprecate old ones on a regular schedule, especially if you suspect exposure. Create distinct keys for development, staging, and production. Revoke dev keys if compromised without affecting production. ## Rotating Keys To rotate an API key: 1. Create a new key 2. Update your application to use the new key 3. Verify the new key works in production 4. Delete the old key There's no downtime during rotation. Both keys work until you delete the old one. ## Revoking Keys To revoke a compromised or unused key: 1. Go to **[API Keys](https://portal.orchestrasolutions.com/#/apikey/create)** in the portal 2. Find the key by name 3. Click **Delete** or **Revoke** The key stops working immediately. ## Choose Your Integration Path You're ready to accept payments. Choose how you want to integrate: **Recommended for most integrations** Pre-built payment UI with Google Pay, Apple Pay, and card entry. Handles 3D Secure automatically. Keeps you out of PCI scope. **For custom payment flows** Direct HTTP calls from your backend. Full control over UI. Use when you have existing payment infrastructure or need maximum flexibility. Not sure which to choose? See the [detailed comparison](https://developers.orchestrasolutions.com/concepts/api-vs-library). --- # Creating eWallet Accounts URL: https://developers.orchestrasolutions.com/getting-started/create-ewallet-account --- eWallet accounts store the merchant configuration needed for the Payments Library to display payment options and process transactions. Each eWallet account defines settings for a specific payment method type. This guide covers eWallet account configuration in detail. For a quick setup to get started, see the [Quickstart](https://developers.orchestrasolutions.com/quickstart). ## What is an eWallet Account? An eWallet account connects your Orchestra integration to specific payment methods through the Payments Library. When you create a session with the Payments Library, you specify which eWallet accounts to use, and the library displays the corresponding payment options to your customers. ## eWallet Account Types | Type | Description | Requirements | |------|-------------|--------------| | **CardPay** | Credit and debit card payments | PSP account configured in Orchestra | | **GooglePay** | Google Pay digital wallet | Google merchant account, PSP with 3DS | | **ApplePay** | Apple Pay digital wallet | Apple merchant account, domain verification, PSP with 3DS | | **PayPal** | PayPal payments | PayPal Business account | | **BankPay** | Bank transfers (Open Banking) | Everifin account, recipient bank details | | **UPI** | Unified Payments Interface (India) | UPI merchant credentials | ## Creating an eWallet Account 1. Go to **[eWallet Accounts > Add Account](https://portal.orchestrasolutions.com/#/resource/eWalletAccount/create)** in the Orchestra Portal 2. Enter a **Name** for the account (e.g., "card-payments", "google-pay-prod") 3. Select the **eWallet Type** for the payment method 4. Configure the type-specific settings (see below) 5. Click **Save** ## CardPay Configuration CardPay accounts enable credit and debit card collection through the Payments Library. | Field | Description | Required | |-------|-------------|----------| | **Merchant Identifier** | Unique identifier for your merchant account, typically in reverse domain format (e.g., `com.yourcompany.payments`) | Yes | | **Merchant Display Name** | Business name shown to customers on the payment form | Yes | | **Display Issue Number?** | Show the card issue number field (used by some UK debit cards) | No | | **Display Owner Id?** | Show a cardholder ID field for markets that require it | No | | **Perform 3Ds?** | Enable 3D Secure authentication for card transactions. When enabled, requires 3DS-related fields below | No | | **Merchant Requestor Id Suffix** | Suffix appended to the 3DS Merchant Requestor ID. Required when **Perform 3Ds** is enabled | Conditional | | **Merchant Url** | Your website URL, sent to the 3DS server. Required when **Perform 3Ds** is enabled | Conditional | ### BIN Routing Table CardPay accounts support optional BIN-based routing. This table lets you route transactions to different Merchant IDs based on card BIN, brand, or MCC. | Column | Description | |--------|-------------| | **Bin** | Card BIN prefix to match (e.g., `411111` for test Visa cards) | | **Brand** | Card brand (Visa, Mastercard, Amex, etc.) | | **MCC** | Merchant Category Code for this routing rule | | **Merchant Id** | The Merchant ID to use when this rule matches | Click **+ Add** to add routing rules. Leave the table empty to use default routing. ## GooglePay Configuration GooglePay accounts enable Google Pay wallet payments through the Payments Library. | Field | Description | Required | |-------|-------------|----------| | **Merchant Identifier** | Your Google Pay Merchant ID from the Google Pay Business Console | Yes | | **Merchant Display Name** | Business name shown in the Google Pay payment sheet | Yes | Before creating a GooglePay eWallet account, you must register as a Google Pay merchant and complete Google's integration requirements. See [Google Pay Setup](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/google-pay) for details. ## ApplePay Configuration ApplePay accounts enable Apple Pay wallet payments through the Payments Library. Apple Pay requires certificates for both merchant validation and payment decryption. | Field | Description | Required | |-------|-------------|----------| | **Merchant Identifier** | Your Apple Merchant ID from the Apple Developer Portal (e.g., `merchant.com.yourcompany`) | Yes | | **Merchant Display Name** | Business name shown in the Apple Pay payment sheet | Yes | | **Domain Name** | The domain where Apple Pay will be used. Must be verified in the Apple Developer Portal | Yes | | **Client Certificate Pem** | Merchant Identity Certificate in PEM format. Used for merchant validation during Apple Pay sessions | Yes | | **Client Certificate Private Key Pem** | Private key for the Merchant Identity Certificate in PEM format | Yes | | **Payment Certificate Private Key Pem** | Private key for the Payment Processing Certificate in PEM format. Used to decrypt payment tokens | Yes | | **Payment Certificate Pem** | Payment Processing Certificate in PEM format | Yes | Apple Pay setup requires creating certificates in the Apple Developer Portal and verifying your domain. See [Apple Pay Setup](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/apple-pay) for step-by-step instructions. ## PayPal Configuration PayPal accounts enable PayPal payments through the Payments Library. | Field | Description | Required | |-------|-------------|----------| | **Merchant Identifier** | Your PayPal Client ID from the PayPal Developer Dashboard | Yes | | **Secret** | Your PayPal Client Secret from the PayPal Developer Dashboard | Yes | You need a PayPal Business account to accept payments. See [PayPal Setup](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/paypal) for details on obtaining your API credentials. ## BankPay Configuration BankPay accounts enable Open Banking payments through the Payments Library, allowing customers to pay directly from their bank account. | Field | Description | Required | |-------|-------------|----------| | **Merchant Identifier** | Unique identifier for your merchant account | Yes | | **Merchant Display Name** | Business name shown to customers during bank selection | Yes | | **Recipient Bank Iban** | Your business bank account IBAN where funds will be deposited | Yes | | **Recipient Bank Bic** | BIC/SWIFT code for your recipient bank account | Yes | | **Everifin Client Id** | Client ID from your Everifin account (Open Banking provider) | Yes | | **Everifin Client Secret** | Client Secret from your Everifin account | Yes | BankPay uses Everifin as the Open Banking provider. Contact Orchestra support to set up an Everifin account for your integration. ## UPI Configuration UPI accounts enable Unified Payments Interface payments for customers in India. | Field | Description | Required | |-------|-------------|----------| | **Merchant Identifier** | Your UPI Merchant ID or Virtual Payment Address (VPA) | Yes | | **Salt** | Cryptographic salt used for secure transaction signing | Yes | UPI is available for merchants operating in India. Contact Orchestra support for UPI integration requirements. ## Using eWallet Accounts When creating a Payments Library session, specify which eWallet accounts to enable: ```bash curl --location 'https://api.orchestrasolutions.com/EWalletOperations' \ --header 'X-Api-Key: YOUR_API_KEY' \ --header 'Content-Type: application/json' \ --data '{ "operation": "CHARGE", "PaymentGatewayAccountId": "your-psp-account", "AllowedeWalletAccountIds": ["card-payments", "google-pay-prod", "paypal-prod"], "mode": "LIVE", "CurrencyCode": "USD", "Amount": "25.00" }' ``` The Payments Library will display payment buttons for each enabled eWallet account that is available on the customer's device/browser. ## Next Steps Full Payments Library configuration CardPay, ApplePay, GooglePay, PayPal, BankPay, UPI --- # Adding a Payment Provider URL: https://developers.orchestrasolutions.com/getting-started/add-payment-provider --- Before making transactions through Orchestra, you need to connect at least one payment provider. Orchestra supports [{supportedIntegrations} gateways](https://orchestrasolutions.com/integrations/) including Stripe, Adyen, Worldpay, Authorize.net, and more. Need a gateway we don't support? [Request an integration](https://orchestrasolutions.com/integration-request/). We add new providers at no cost within 2-4 weeks. ## Prerequisites - An Orchestra account ([sign up here](https://portal.orchestrasolutions.com)) - A payment gateway account with API credentials ## Add a Provider In the Orchestra portal, go to **[Payment Gateway Account > Create](https://portal.orchestrasolutions.com/#/resource/paymentGateway/create)**. Fill in the required fields: | Field | Description | |-------|-------------| | **Name** | A unique identifier for this gateway account (e.g., "stripe-test", "adyen-production"). Used in API calls to specify which gateway to use. | | **Username** | (Create only) Optionally assign this gateway account to a specific user. If blank, the account is available to all users. | | **Payment Gateway Name** | Select your payment provider from the dropdown | | **Credentials** | Provider-specific fields appear after selecting a gateway. Enter your API credentials from your gateway's dashboard. | The credentials fields change based on the gateway you select. Common fields include API keys, terminal IDs, merchant IDs, and secret keys. Click **Save**. Your provider is now connected and ready for transactions. ## Gateway Credentials Each gateway requires different credentials. Here are examples for common providers: - **API Key**: Your Stripe secret key (starts with `sk_test_` or `sk_live_`) Find these in your [Stripe Dashboard](https://dashboard.stripe.com/apikeys) under Developers > API Keys. - **Merchant Account**: Your merchant account name - **Username** and **Password**: Your Adyen username and password - **Company Name**: Your company name in Adyen Find these in your [Adyen Customer Area](https://ca-test.adyen.com/) under Developers > API credentials. - **SecurenetId**: Your unique merchant identifier for WorldPay's API. - **SecureNetKey**: Your API authentication key for WorldPay backend configurations. Find these in your Worldpay Virtual Terminal under Settings > Key Management (or Settings > Obtain Secure Key). ## Test vs Production Credentials Always use test/sandbox credentials during development. Production credentials will process real transactions. Most gateways provide separate test and production credentials: | Environment | Use For | |------------|---------| | Test/Sandbox | Development, testing, CI/CD | | Production/Live | Real customer transactions | When you're ready to go live, create a new Payment Gateway Account with your production credentials. You can keep both test and production accounts configured and reference them by name in your API calls. ## Next Steps Create credentials for API access Make your first charge --- # Testing & Going Live URL: https://developers.orchestrasolutions.com/concepts/testing-and-going-live --- Orchestra uses the same API for both testing and production. The environment is determined by your credentials, not the API endpoint. ## Sandbox vs Production | Environment | Use Case | Behavior | |-------------|----------|----------| | Sandbox | Development, testing, CI/CD | Transactions simulated via provider test modes | | Production | Live customer transactions | Real money moves | The API base URL is the same for both environments: https://api.orchestrasolutions.com ## How Environments Work Orchestra doesn't have a global "test mode" switch. Instead, the environment is determined by: 1. **Your Payment Gateway Account credentials** - Test credentials (e.g., Stripe's `sk_test_...`) route to sandbox; live credentials route to production 2. **The `mode` parameter** (Payments Library only) - Set to `TEST` or `LIVE` when creating sessions This means you can run both environments simultaneously by using different Payment Gateway Account names in your API calls. ## Setting Up for Testing ### Quick Start with Mock PSPs For immediate testing without external provider accounts, use Orchestra's built-in mock payment gateways: 1. In the Portal, go to **[Payment Gateway Account > Create](https://portal.orchestrasolutions.com/#/resource/paymentGateway/create)** 2. Select **NULLSuccess** or **NULLFailure** as the gateway 3. Give it a name (e.g., "test-success") 4. Leave credentials empty 5. Use the account name in your API calls Mock PSPs simulate basic success/failure scenarios instantly, with no external dependencies. See [Mock PSPs](https://developers.orchestrasolutions.com/guides/utilities/mock-psps) for complete details and limitations. ### 1. Create Test Payment Gateway Accounts For comprehensive testing with real provider features, use your provider's test/sandbox credentials: ``` Name: stripe-test Gateway: Stripe Credentials: sk_test_... ``` ### 2. Use Test API Keys Create separate API keys for development. Label them clearly (e.g., "Development", "CI/CD"). Never use production API keys in development environments or commit them to version control. ### 3. Use Test Card Numbers Each payment provider has test card numbers that simulate various scenarios: | Provider | Test Card | Notes | |----------|-----------|-------| | Stripe | `4111111111111111` | Successful charge | | Stripe | `4000000000000002` | Card declined | | Adyen | `4111111111111111` | Successful charge | Check your payment provider's documentation for their full list of test cards and scenario simulations (3DS challenges, insufficient funds, etc.). ## Payments Library Mode When using the Payments Library, set the `mode` parameter in your session request: ```json { "operation": "CHARGE", "mode": "TEST", "amount": 25.00, "currencyCode": "USD", "paymentGatewayAccountId": "stripe-test" } ``` | Mode | Behavior | |------|----------| | `TEST` | Sandbox transactions | | `LIVE` | Production transactions | ## Going Live Checklist When you're ready to accept real payments: Add your payment providers with live/production credentials: ``` Name: stripe-production Gateway: Stripe Credentials: sk_live_... ``` Create new API keys specifically for production. Use environment variables or a secrets manager. Change your code to reference production account names: ```javascript // Development paymentGatewayAccountName: 'stripe-test' // Production paymentGatewayAccountName: 'stripe-production' ``` For the Payments Library, change `mode` from `TEST` to `LIVE`. Before full launch, process a few small real transactions to verify everything works end-to-end. ## Running Both Environments You can maintain both sandbox and production in the same Orchestra account: ```javascript // Use environment variables to switch const accountName = process.env.NODE_ENV === 'production' ? 'stripe-production' : 'stripe-test'; const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': process.env.ORCHESTRA_API_KEY }, body: JSON.stringify({ amount: 25.00, currency: 'USD', paymentGatewayAccountName: accountName, card: { ... } }) }); ``` ## Best Practices Use distinct API keys, Payment Gateway Accounts, and environment variables for each environment. Don't use test credentials in production or vice versa. Label accounts clearly. CI/CD pipelines should only have access to test credentials. Production deploys should pull from secure secrets. Watch your first production transactions closely. Verify amounts, success rates, and provider responses. ## Related Sign up for Orchestra Connect your gateways Create API credentials Authentication and endpoints --- # How Orchestra Works URL: https://developers.orchestrasolutions.com/concepts/how-orchestra-works --- Orchestra is a payment orchestration layer that sits between your application and your payment providers. It provides a unified API while routing transactions to the providers you choose. ## The Problem Orchestra Solves Without Orchestra, integrating multiple payment providers means: - Writing and maintaining separate integrations for each provider - Handling different APIs, data formats, and authentication methods - Building your own failover logic when a provider goes down - Re-integrating when you want to add or switch providers Orchestra handles all of this with a single integration. ## Where Orchestra Fits Your application makes API calls to Orchestra. Orchestra translates those calls to the appropriate provider format and routes the transaction. ## What Orchestra Handles | Orchestra Does | You Handle | |---------------|------------| | Provider API translation | Business logic (what to charge, when) | | Credential management | Customer data (accounts, orders) | | Transaction routing | User interface | | Token storage | Compliance for your stored data | | Failover execution | Provider account setup | ## Transaction Flow Your server sends a charge request to Orchestra with the amount, currency, and payment details. Based on the `paymentGatewayAccountName` you specify, Orchestra sends the transaction to the appropriate provider. Stripe, Adyen, or whichever provider you specified processes the transaction with the card network and issuing bank. You receive a standardized response with the transaction ID and status. ## Key Concepts ### Payment Gateway Accounts A Payment Gateway Account is your connection to a specific provider. You create one for each provider account you want to use: - "stripe-production" → Your Stripe live account - "stripe-test" → Your Stripe test account - "adyen-backup" → Your Adyen account for failover When making API calls, you specify which account to use by name. ### Tokens Orchestra's tokenization stores card details securely and gives you a token reference. Tokens are provider-agnostic. A card tokenized while routing through Stripe can later be charged through Adyen. ### Routing You control routing by specifying the `paymentGatewayAccountName` in each request. This lets you: - Use different providers for different markets - Route high-value transactions to preferred providers - Implement A/B testing across providers ## Sandbox vs Production Orchestra provides both environments: | Environment | Use | Provider Mode | |-------------|-----|---------------| | Sandbox | Development, testing | Connect to provider test/sandbox accounts | | Production | Live transactions | Connect to provider live accounts | Sandbox transactions are simulated. No real money moves. The API behavior is identical to production. Use separate API keys and Payment Gateway Accounts for sandbox and production. Don't mix test credentials with live ones. ## Related Guides Make your first API call Connect your PSP accounts Technical architecture details Set up automatic failover --- # Payments Library vs REST API URL: https://developers.orchestrasolutions.com/concepts/api-vs-library --- Orchestra offers two integration approaches. Both provide automatic gateway failover and access to {supportedIntegrations} payment providers. ## Quick Comparison | Capability | Payments Library | REST API | |------------|-------------------|----------| | Integration method | npm package | Direct HTTP calls | | Card collection | We handle it | You handle it | | PCI compliance | Out of scope | Your responsibility | | UI control | Pre-built components | Full customization | | 3D Secure | Built-in | Manual implementation | | Digital wallets | Native support | API integration required | | Deployment speed | Rapid | Custom development | ## Choose Library if you: - Want the fastest path to accepting payments - Prefer to stay out of PCI scope - Need Google Pay, Apple Pay, or bank transfers quickly - Want battle-tested payment UX - Don't want to build payment UI from scratch [Get started with Library →](https://developers.orchestrasolutions.com/quickstart) ## Choose REST API if you: - Have existing payment flows you want to enhance - Need pixel-perfect UI control - Already handle PCI compliance - Use third-party tokenization providers - Prefer backend-only integration [Get started with REST API →](https://developers.orchestrasolutions.com/quickstart) ## Can I use both? Yes. Many implementations use the Library for customer-facing payments and the REST API for backend operations like refunds, reporting, or recurring billing. ## Related Guides Full Payments Library integration REST API charge implementation Get started in 5 minutes Full working code sample --- # Architecture URL: https://developers.orchestrasolutions.com/concepts/architecture --- This page describes Orchestra's technical architecture for developers who want to understand how the system works under the hood. ## System Overview ![Orchestra Architecture Overview](https://developers.orchestrasolutions.com/images/architecture-overview.svg) ## Components ### API Gateway The entry point for all requests. Handles: - TLS termination - Authentication (API key validation) - Rate limiting - Request routing to internal services ### Payment Gateway Service Processes payment transactions: - Translates Orchestra's unified API to provider-specific formats - Routes transactions to the specified Payment Gateway Account - Handles provider responses and normalizes them - Manages transaction state (authorization, capture, void, refund) ### Payment Gateway Accounts Service Manages provider connections: - Stores encrypted credentials - Validates account configuration - Handles credential rotation ### Tokenization Service Secures card data: - Encrypts and stores card details - Issues tokens for stored cards - Retrieves card data for transactions (never exposed to your systems) ## Data Flow: Charge Transaction Your server sends a POST to `/PaymentGateway/charge` with amount, currency, payment gateway account name, and card details (or token). API Gateway validates your API key and checks permissions. Payment Gateway Service looks up the specified Payment Gateway Account to get provider type and credentials. If you sent a `cardToken`, Tokenization Service retrieves the stored card data. Payment Gateway Service translates your request to the provider's format and sends it to the provider's API. Provider response is normalized to Orchestra's format and returned to you. ## Security ### Data at Rest - All sensitive data (credentials, card numbers) encrypted with AES-256 - Encryption keys managed via HSM (Hardware Security Module) - Database access restricted to service accounts ### Data in Transit - All API traffic over TLS 1.2+ - Provider communications over their required secure protocols - No sensitive data in URLs or logs ### PCI Compliance Orchestra is PCI DSS Level 1 compliant. When you use Orchestra's tokenization, card data never touches your systems, reducing your PCI scope. See our [PCI compliance documentation](https://orchestrasolutions.com/about/pci-compliance/) for details. ## Reliability ### Availability - Multi-region deployment - Automatic failover between availability zones - 99.9% uptime SLA ### Failover Orchestra supports two approaches for payment failure recovery: **1. Built-in Sequential Failover (Payments Library)** When using the [Payments Library](https://developers.orchestrasolutions.com/guides/library/setup), pass a list of fallback Payment Gateway Accounts in the session request. Orchestra tries each one in order until a payment succeeds or all fail: ```json { "operation": "CHARGE", "paymentGatewayAccountId": "stripe-primary", "fallbackUpgs": [ { "paymentGatewayAccountId": "adyen-backup" }, { "paymentGatewayAccountId": "worldpay-fallback" } ], "amount": 99.99, "currencyCode": "USD" } ``` If `stripe-primary` fails, Orchestra automatically tries `adyen-backup`, then `worldpay-fallback`. **2. Custom Retry Logic (REST API)** When using the REST API directly, implement your own failover logic for full control over retry conditions: ```javascript async function chargeWithFailover(amount, currency, cardToken) { const providers = ['stripe-primary', 'adyen-backup']; for (const provider of providers) { try { const result = await charge(amount, currency, provider, cardToken); if (result.success) return result; } catch (error) { console.log(`${provider} failed, trying next`); } } throw new Error('All providers failed'); } ``` The built-in approach is simpler, while custom logic lets you add conditions like retrying only on specific error codes or routing based on transaction attributes. ## Latency Typical response times: | Operation | Latency | |-----------|---------| | Tokenization | 50-100ms | | Charge/Authorize | 200-500ms (depends on provider) | | Balance check | 20-50ms | Provider latency dominates transaction times. Orchestra adds minimal overhead (~20-50ms). ## Related Guides Implement your first charge Set up automatic failover Securely store card data Full endpoint documentation --- # Library Setup URL: https://developers.orchestrasolutions.com/guides/library/setup --- This page is part of the **Payments Library Guides**. Prefer direct API calls instead? See [REST API Guides](https://developers.orchestrasolutions.com/guides/rest-api/charge). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key), [Payment Gateway Account](https://developers.orchestrasolutions.com/getting-started/add-payment-provider), and [eWallet Account](https://developers.orchestrasolutions.com/guides/library/store-merchant-account) configured. The Orchestra Payments Library displays payment buttons and handles the payment UI. It supports card entry, Apple Pay, Google Pay, PayPal, bank payments, and UPI. Available on npm as @orchestrasolutions/ewallet. ## Installation ```bash npm install @orchestrasolutions/ewallet ``` ### CDN Usage ```html ``` When loading via CDN, the library attaches to `window.eWallet`: ```javascript const engine = new eWallet.Engine(sessionToken); ``` ## Data Flow ![Payments Library Data Flow](https://developers.orchestrasolutions.com/images/payments-library-flow-d2.svg) Your server creates a session with Orchestra and passes the JWT to the client. The client initializes the library, displays payment buttons, and handles customer interaction. After payment, the result JWT is returned to the client, which passes it to your server for validation with Orchestra. ## Quick Start ### 1. Initialize the Engine ```javascript const engine = new eWallet.Engine(sessionToken); ``` The `sessionToken` comes from your backend via [POST /EWalletOperations](https://developers.orchestrasolutions.com/api-reference/ewalletoperations/start-an-ewallet-session). ### 2. Check Available Payment Methods ```javascript const available = await engine.checkAvailability(); // Returns: ["CardPay", "GooglePay", "PayPal", ...] ``` ### 3. Display Buttons Add container elements to your HTML: ```html ``` Each payment method requires its own container element with a unique selector. If you add multiple payment methods, create a separate container for each. Render buttons for available methods: ```javascript const buttons = [ { name: 'CardPay', domEntitySelector: '#card-button' }, { name: 'GooglePay', domEntitySelector: '#gpay-button' }, { name: 'PayPal', domEntitySelector: '#paypal-button' } ].filter(btn => available.includes(btn.name)); engine.payBy(buttons, handleResult, undefined); ``` ### 4. Handle Results ```javascript function handleResult(result) { if (!result) { console.log('Payment cancelled'); return; } // Send token to your backend for validation fetch('/api/validate-payment', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token: result.token }) }); } ``` Your backend should validate the result token using [POST /EWalletOperations/validateResults](https://developers.orchestrasolutions.com/api-reference/ewalletoperations/validate-operation-results) before fulfilling orders. ## Payment Methods | Value | Description | Availability | |-------|-------------|--------------| | `"CardPay"` | Credit/debit card form | All browsers | | `"GooglePay"` | Google Pay | Chrome, Android | | `"ApplePay"` | Apple Pay | Safari, iOS, macOS | | `"PayPal"` | PayPal checkout | All browsers | | `"BankPay"` | Bank transfer (Open Banking, ACH) | All browsers | | `"UPI"` | Unified Payments Interface | All browsers | ## What's Next CardPay, ApplePay, GooglePay, PayPal, BankPay, UPI Button styling, result parsing, address collection, localization Parse and validate payment results End-to-end integration example --- # Library Reference URL: https://developers.orchestrasolutions.com/guides/library/reference --- This page is part of the **Payments Library Guides**. Prefer direct API calls instead? See [REST API Guides](https://developers.orchestrasolutions.com/guides/rest-api/charge). ## Engine Constructor ```javascript const engine = new eWallet.Engine( sessionToken, // Required: from POST /EWalletOperations requiredAncillaryInfo, // Optional: address collection requirements language, // Optional: UI language code uiOptions // Optional: UI display options ); ``` | Parameter | Type | Description | |-----------|------|-------------| | `sessionToken` | `string` | Session token from your backend via [POST /EWalletOperations](https://developers.orchestrasolutions.com/api-reference/ewalletoperations/start-an-ewallet-session) | | `requiredAncillaryInfo` | `RequiredAncillaryInfo \| undefined` | Billing/shipping address requirements (see [Address Collection](#address-collection)) | | `language` | `string \| undefined` | Language code for UI (see [Localization](#localization)) | | `uiOptions` | `UiOptions \| undefined` | Display options for the CardPay form (see [UI Options](#ui-options)) | ## UI Options Control how the CardPay card-entry form is displayed. Other providers are not affected. ```javascript const uiOptions = { hideLogo: true, // hide merchant logo on card form displayMode: 'iframe', // 'popup' (default) or 'iframe' iframeContainerSelector: '#card-form' // CSS selector for inline iframe host }; const engine = new eWallet.Engine(sessionToken, requiredAncillaryInfo, language, uiOptions); ``` | Field | Type | Description | |-------|------|-------------| | `hideLogo` | `boolean` | When `true`, the merchant logo is not rendered on the card-entry form. Defaults to `false`. | | `displayMode` | `'popup' \| 'iframe'` | `'popup'` (default) opens the card form in a separate browser window. `'iframe'` embeds it in-page. | | `iframeContainerSelector` | `string` | Only used when `displayMode` is `'iframe'`. CSS selector of the element that hosts the iframe (e.g. `'#card-form'`). When omitted, the iframe is shown as a centered modal overlay. | `displayMode` applies to the CardPay form only. Apple Pay, Google Pay, PayPal, BankPay, and UPI continue to use their standard flows. ## Localization The library supports 20 languages. Pass a language code to the constructor: ```javascript const engine = new eWallet.Engine(sessionToken, undefined, 'de'); ``` ### Supported Languages | Code | Language | Code | Language | |------|----------|------|----------| | `en` | English | `nl` | Dutch | | `de` | German | `pl` | Polish | | `es` | Spanish | `pt` | Portuguese | | `fr` | French | `ru` | Russian | | `it` | Italian | `sv` | Swedish | | `he` | Hebrew | `tr` | Turkish | | `cs` | Czech | `zh` | Chinese | | `el` | Greek | `ko` | Korean | | `fi` | Finnish | `sk` | Slovak | | `no` | Norwegian | `sr` | Serbian | ## checkAvailability() Returns the list of payment methods available on the current device and browser: ```javascript const available = await engine.checkAvailability(); // Returns: ["CardPay", "GooglePay", "PayPal", ...] ``` Use this to filter which buttons to display. For example, Apple Pay is only available on Safari/iOS, and Google Pay only on Chrome/Android. ## payBy() Method ```javascript engine.payBy( eWalletList, // Required: buttons to display callback, // Required: called when payment completes buttonProperties, // Optional: button styling requiredAncillaryInfo // Optional: override address requirements ); ``` Each button is an object with `name` and `domEntitySelector`: ```javascript { name: 'CardPay', domEntitySelector: '#card-button' } ``` ## Button Styling Customize button appearance with `ButtonProperties`: ```javascript const buttonProperties = { color: 'Dark', // "Light" or "Dark" text: 'Pay', // "None", "Pay", "Buy", "Subscribe", "Book", "Checkout", "Donate" width: '200px', height: '40px', logoPath: '/path/to/logo.png' // Optional }; engine.payBy(buttons, handleResult, buttonProperties); ``` ## Parsing Results Use `parseResultToken()` to decode the result token into structured data: ```javascript function handleResult(result) { if (!result) return; const [data, success] = engine.parseResultToken(result.token); ``` The method returns a tuple: - `data` - The parsed result object containing payment details - `success` - Boolean indicating if the token was successfully decoded (not whether the payment succeeded) To determine if a payment succeeded, check `data.clientSuccess`: ```javascript if (!data.clientSuccess) { console.error('Payment failed:', data.clientErrorMessage); return; } // Check which type of result we received if (data.upgChargeResults) { // Payment processed through a PSP (CardPay, ApplePay, GooglePay) console.log('Gateway:', data.upgChargeResults.gatewayName); console.log('Reference:', data.upgChargeResults.gatewayReference); console.log('Amount:', data.upgChargeResults.amount, data.upgChargeResults.currency); } if (data.directChargeResults) { // Payment processed directly (PayPal, BankPay, UPI) console.log('Success:', data.directChargeResults.success); console.log('Message:', data.directChargeResults.message); } if (data.tokenAndMaskedCardModel) { // Tokenization result console.log('Token:', data.tokenAndMaskedCardModel.token); console.log('Card:', data.tokenAndMaskedCardModel.bankCard.type); console.log('Last 4:', data.tokenAndMaskedCardModel.bankCard.number); if (data.tokenAndMaskedCardModel.threeDs) { console.log('3DS ECI:', data.tokenAndMaskedCardModel.threeDs.eci); } } } ``` ### getSessionType() Returns the operation type for this session: ```javascript const sessionType = engine.getSessionType(); // "CHARGE", "TOKENIZE", "CHARGE_AND_TOKENIZE", "PREAUTH_AND_TOKENIZE", or "GATEWAY_TOKENIZE" ``` ### getSelectedProviderName() Returns which payment method the customer used: ```javascript function handleResult(result) { const provider = engine.getSelectedProviderName(); console.log('Customer paid with:', provider); // "CardPay", "GooglePay", "ApplePay", "PayPal", "BankPay", or "UPI" } ``` ### Result Data Structure ```typescript EWalletResultData { clientSuccess: boolean; clientErrorMessage: any; // For PSP charges (CardPay, ApplePay, GooglePay) upgChargeResults?: { gatewayName: string; gatewayReference: string; authorizationCode: string; amount: number; currency: string; operationType: string; // "Charge", "PreAuth", etc. operationResultCode: string; // "Success", "Rejected", etc. operationResultDescription: string; // Human-readable result message gatewayResultDescription: string; // Message from the payment gateway }; // For direct charges (PayPal, BankPay, UPI) directChargeResults?: { success: boolean; message: string; data: object; // Provider-specific payload - structure varies by payment method. See note below. }; // For tokenization tokenAndMaskedCardModel?: { token: string; bankCard: { type: string; // "Visa", "Mastercard", etc. number: string; // Masked: "************1234" expirationMonth: number; expirationYear: number; nameOnCard: string; }; threeDs?: { eci: string; authenticationValue: string; xid: string; version: string; }; }; } ``` `directChargeResults.data` is intentionally untyped. Its contents are provider-specific (PayPal, BankPay, UPI each return different fields) and may change as those providers update their APIs. Use `success` and `message` to determine the payment outcome - do not build logic that depends on the contents of `data`. ## Address Collection Request billing and/or shipping addresses from the payment method (supported by Google Pay, Apple Pay, PayPal). ### Configuration ```javascript const requiredAncillaryInfo = { billingInfo: { phoneRequired: true, emailAddressRequired: true, details: 'FULL' // "MIN" or "FULL" }, shippingInfo: { phoneRequired: false, emailAddressRequired: false } }; const engine = new eWallet.Engine(sessionToken, requiredAncillaryInfo); ``` ### Address Levels | Level | Fields Included | |-------|-----------------| | `"MIN"` | name, countryCode, postalCode, phone (if required), email (if required) | | `"FULL"` | MIN fields + addressLines, locality (city), administrativeArea (state/province) | ### Retrieving Addresses After payment completes, retrieve the collected addresses: ```javascript function handleResult(result) { if (!result) return; const billing = engine.getBillingInfo(); if (billing) { console.log('Name:', billing.name); console.log('Email:', billing.emailAddress); console.log('Country:', billing.countryCode); console.log('Postal:', billing.postalCode); // FULL address fields (if requested) if (billing.addressLines) { console.log('Street:', billing.addressLines.join(', ')); console.log('City:', billing.locality); console.log('State:', billing.administrativeArea); } } const shipping = engine.getShippingInfo(); if (shipping) { console.log('Ship to:', shipping.name); console.log('Address:', shipping.addressLines?.join(', ')); } } ``` ## Operations The session operation (set when creating the session) determines what the library does: | Operation | Description | |-----------|-------------| | `CHARGE` | Process payment immediately | | `TOKENIZE` | Store payment method, return token for later charges | | `CHARGE_AND_TOKENIZE` | Process payment and return a token | | `PREAUTH_AND_TOKENIZE` | Authorize payment and return a token for later capture | | `GATEWAY_TOKENIZE` | Tokenize the card directly at the payment gateway | Tokenization is only available for CardPay, ApplePay, and GooglePay. PayPal, BankPay, and UPI support charge only. ## Payment Method Requirements ### CardPay, ApplePay, GooglePay Requires a payment processor (PSP) configured in your Orchestra account. Pass `paymentGatewayAccountId` when creating the session. Orchestra supports [{supportedIntegrations} payment gateways](https://orchestrasolutions.com/integrations/). ### ApplePay, GooglePay In addition to PSP credentials, these require: - Merchant registration with Apple/Google - Domain verification - A PSP that [supports 3DS](https://orchestrasolutions.com/integ-type/3d-secure/) See [ApplePay Setup](https://developers.orchestrasolutions.com/guides/library/applepay-setup) and [GooglePay Setup](https://developers.orchestrasolutions.com/guides/library/googlepay-setup) for details. ### PayPal Requires PayPal merchant credentials [configured in the Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/eWalletAccount/create). See [PayPal Setup](https://developers.orchestrasolutions.com/guides/library/paypal-setup) for details. ### BankPay Requires an Open Banking or ACH provider account [configured in the Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/eWalletAccount/create). [Contact our team](https://orchestrasolutions.com/contact/) to confirm regional support. ### UPI Requires a UPI provider account [configured in the Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/eWalletAccount/create). Only available for INR transactions in India. ## Related Quick start guide All payment methods Parse payment results Backend endpoint reference --- # Complete Example URL: https://developers.orchestrasolutions.com/guides/library/complete-example --- This page is part of the **Payments Library Guides**. Prefer direct API calls instead? See [REST API Guides](https://developers.orchestrasolutions.com/guides/rest-api/charge). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key), [Payment Gateway Account](https://developers.orchestrasolutions.com/getting-started/add-payment-provider), and [eWallet Account](https://developers.orchestrasolutions.com/guides/library/store-merchant-account) configured. This page provides a complete working example showing how to integrate the Orchestra Payments Library from server to client. Clone the complete example project ## Server-Side: Create Session Your server creates a session with the Orchestra API and returns the token to the client. ```javascript Node.js const express = require('express'); const app = express(); // eWallet account IDs from environment variables const eWalletAccounts = { cardPay: process.env.EWALLET_CARDPAY_ACCOUNT_ID, googlePay: process.env.EWALLET_GOOGLEPAY_ACCOUNT_ID, applePay: process.env.EWALLET_APPLEPAY_ACCOUNT_ID, payPal: process.env.EWALLET_PAYPAL_ACCOUNT_ID, }; // Build array of only the configured account IDs // Note: This helper is for the example's flexibility. In practice, you would // simply list your eWallet account names directly in the request, e.g.: // allowedeWalletAccountIds: ['my-cardpay-account', 'my-paypal-account'] function getConfiguredEWalletAccountIds() { return Object.values(eWalletAccounts).filter(Boolean); } app.post('/api/create-session', async (req, res) => { const response = await fetch('https://api.orchestrasolutions.com/EWalletOperations', { method: 'POST', headers: { 'X-Api-Key': process.env.ORCHESTRA_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify({ operation: 'CHARGE', paymentGatewayAccountId: process.env.PAYMENT_GATEWAY_ACCOUNT_ID, allowedeWalletAccountIds: getConfiguredEWalletAccountIds(), allowedBrands: ['VISA', 'MASTERCARD', 'AMEX'], currencyCode: 'USD', countryCode: 'US', amount: 49.99, mode: 'TEST' }) }); const data = await response.json(); res.json({ sessionToken: data.token }); }); app.listen(3000); ``` ```python Python from flask import Flask, jsonify app = Flask(__name__) # eWallet account IDs from environment variables ewallet_accounts = { 'cardPay': os.environ.get('EWALLET_CARDPAY_ACCOUNT_ID'), 'googlePay': os.environ.get('EWALLET_GOOGLEPAY_ACCOUNT_ID'), 'applePay': os.environ.get('EWALLET_APPLEPAY_ACCOUNT_ID'), 'payPal': os.environ.get('EWALLET_PAYPAL_ACCOUNT_ID'), } # Build list of only the configured account IDs # Note: This helper is for the example's flexibility. In practice, you would # simply list your eWallet account names directly in the request, e.g.: # 'allowedeWalletAccountIds': ['my-cardpay-account', 'my-paypal-account'] def get_configured_ewallet_account_ids(): return [v for v in ewallet_accounts.values() if v] @app.route('/api/create-session', methods=['POST']) def create_session(): response = requests.post( 'https://api.orchestrasolutions.com/EWalletOperations', headers={ 'X-Api-Key': os.environ['ORCHESTRA_API_KEY'], 'Content-Type': 'application/json' }, json={ 'operation': 'CHARGE', 'paymentGatewayAccountId': os.environ['PAYMENT_GATEWAY_ACCOUNT_ID'], 'allowedeWalletAccountIds': get_configured_ewallet_account_ids(), 'allowedBrands': ['VISA', 'MASTERCARD', 'AMEX'], 'currencyCode': 'USD', 'countryCode': 'US', 'amount': 49.99, 'mode': 'TEST' } ) result = response.json() return jsonify({'sessionToken': result['token']}) if __name__ == '__main__': app.run(port=3000) ``` ## Client-Side: HTML Create container elements for each payment method you want to display: ```html Checkout Complete Your Purchase Total: $49.99 ``` ## Client-Side: JavaScript Initialize the library and render payment buttons: ```javascript // checkout.js let engine = null; async function initPayment() { // 1. Get session token from your server const response = await fetch('/api/create-session', { method: 'POST' }); const { sessionToken } = await response.json(); // 2. Initialize the engine engine = new eWallet.Engine(sessionToken); // 3. Check which payment methods are available const available = await engine.checkAvailability(); console.log('Available payment methods:', available); // 4. Build list of buttons to display const allButtons = [ { name: 'CardPay', domEntitySelector: '#card-button' }, { name: 'GooglePay', domEntitySelector: '#gpay-button' }, { name: 'ApplePay', domEntitySelector: '#applepay-button' }, { name: 'PayPal', domEntitySelector: '#paypal-button' } ]; const buttons = allButtons.filter(btn => available.includes(btn.name)); // 5. Render the buttons engine.payBy(buttons, handleResult, { color: 'Dark', text: 'Pay' }); } async function handleResult(result) { const resultEl = document.getElementById('result'); // User cancelled if (!result) { resultEl.textContent = 'Payment cancelled'; return; } // Parse the result token const [data, success] = engine.parseResultToken(result.token); console.log('Payment result:', data); // Check if payment succeeded if (!data.clientSuccess) { resultEl.textContent = 'Payment failed: ' + (data.clientErrorMessage || 'Unknown error'); return; } // Handle PSP charge results (CardPay, GooglePay, ApplePay) if (data.upgChargeResults) { if (data.upgChargeResults.operationResultCode === 'Success') { resultEl.innerHTML = ` Payment successful! Gateway: ${data.upgChargeResults.gatewayName} Reference: ${data.upgChargeResults.gatewayReference} Amount: ${data.upgChargeResults.amount} ${data.upgChargeResults.currency} `; } else { resultEl.textContent = 'Payment declined: ' + (data.upgChargeResults.operationResultDescription || data.upgChargeResults.operationResultCode); return; } } // Handle direct charge results (PayPal, BankPay) if (data.directChargeResults) { if (data.directChargeResults.success) { resultEl.innerHTML = 'Payment successful!Provider: PayPal'; } else { resultEl.textContent = 'Payment failed: ' + data.directChargeResults.message; return; } } // Server-side validation (recommended for production) try { const validationResponse = await fetch('/api/validate-payment', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ resultToken: result.token }) }); if (validationResponse.ok) { const validationResult = await validationResponse.json(); console.log('Server validation:', validationResult); } } catch (error) { console.warn('Could not reach server for validation:', error.message); } } // Start when page loads document.addEventListener('DOMContentLoaded', initPayment); ``` ## Server-Side: Validate Results After a successful payment, validate the result token with Orchestra to confirm the payment: ```javascript Node.js app.post('/api/validate-payment', async (req, res) => { const { resultToken } = req.body; const response = await fetch('https://api.orchestrasolutions.com/EWalletOperations/validateResults', { method: 'POST', headers: { 'X-Api-Key': process.env.ORCHESTRA_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify(resultToken) }); const validationResult = await response.json(); if (validationResult.clientSuccess) { // Payment confirmed - fulfill the order res.json({ success: true, data: validationResult }); } else { res.json({ success: false, error: validationResult.clientErrorMessage }); } }); ``` ```python Python @app.route('/api/validate-payment', methods=['POST']) def validate_payment(): data = request.json result_token = data['resultToken'] response = requests.post( 'https://api.orchestrasolutions.com/EWalletOperations/validateResults', headers={ 'X-Api-Key': os.environ['ORCHESTRA_API_KEY'], 'Content-Type': 'application/json' }, data=json.dumps(result_token) ) result = response.json() if result.get('clientSuccess'): # Payment confirmed - fulfill the order return jsonify({'success': True, 'data': result}) else: return jsonify({'success': False, 'error': result.get('clientErrorMessage')}) ``` ## Related Installation and quick start Full API reference Session creation endpoint Result validation endpoint --- # Supported Payment Methods URL: https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/index --- This page is part of the **Payments Library Guides**. [Back to Library Setup →](https://developers.orchestrasolutions.com/guides/library/setup) The Orchestra Payments Library supports multiple payment methods through a unified API. Each payment method has its own availability requirements and user experience, but all follow the same integration pattern. ## Available Payment Methods Credit and debit card payments with built-in validation and 3D Secure support. One-tap payments for Apple devices with Face ID or Touch ID authentication. Fast checkout for Android devices and Chrome browsers. Redirect-based payments using customer's PayPal account. Direct bank transfers via Open Banking (PSD2) or ACH. India's Unified Payments Interface for instant bank transfers. ## Availability at a Glance | Payment Method | Desktop | Mobile Web | iOS App | Android App | |----------------|---------|------------|---------|-------------| | CardPay | Yes | Yes | Yes | Yes | | Apple Pay | Safari only | Safari only | Yes | No | | Google Pay | Chrome | Chrome | No | Yes | | PayPal | Yes | Yes | Yes | Yes | | BankPay | Yes | Yes | Yes | Yes | | UPI | Yes | Yes | Yes | Yes | ## Common Integration Pattern All payment methods follow the same integration pattern: ```javascript // 1. Check availability const available = await engine.checkAvailability(); // 2. Filter to available methods const buttons = [ { name: 'CardPay', domEntitySelector: '#card-button' }, { name: 'ApplePay', domEntitySelector: '#applepay-button' }, { name: 'GooglePay', domEntitySelector: '#gpay-button' }, { name: 'PayPal', domEntitySelector: '#paypal-button' } ].filter(btn => available.includes(btn.name)); // 3. Render buttons engine.payBy(buttons, handleResult, { color: 'Dark', text: 'Pay' }); ``` ## Result Handling All payment methods return results through the same callback. See [Result Handling](https://developers.orchestrasolutions.com/guides/library/result-handling) for details on parsing and validating payment results. ## Related Get started with the Payments Library Parse and validate payment results --- # CardPay URL: https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/card-pay --- This page is part of **Supported Payment Methods**. [View all payment methods →](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods) CardPay displays a secure card entry form where customers enter their card details. The form handles validation, formatting, and card brand detection automatically. ## Availability CardPay is available on all browsers and devices. It appears in `checkAvailability()` results when properly configured. | Platform | Availability | |----------|--------------| | Desktop browsers | Yes | | Mobile browsers | Yes | | iOS apps | Yes | | Android apps | Yes | ## Requirements CardPay requires: - A payment gateway (PSP) account from one of our [supported payment gateways](https://orchestrasolutions.com/integrations/), configured in [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/paymentGateway) - A CardPay eWallet account configured in [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/eWalletAccount) ```javascript // Server-side session creation const session = { operation: 'CHARGE', paymentGatewayAccountId: 'your-psp-account', allowedeWalletAccountIds: ['your-cardpay-account'], allowedBrands: ['VISA', 'MASTERCARD', 'AMEX'], amount: 25.00, currencyCode: 'USD', countryCode: 'US', mode: 'LIVE' }; ``` ## Button Setup ```html ``` ```javascript engine.payBy( [{ name: 'CardPay', domEntitySelector: '#card-button' }], handleResult, { color: 'Dark', text: 'Pay' } ); ``` ## How It Works 1. Customer clicks the CardPay button 2. A secure popup window opens with the card entry form 3. Customer enters card number, expiry, CVV, and name 4. The form validates input in real-time 5. If 3D Secure is required, the authentication flow is handled automatically with no additional code required 6. Orchestra processes the payment through your PSP 7. On completion, the popup closes and results are returned to the client, ready to be sent to your server for validation ## Supported Operations | Operation | Supported | Description | |-----------|-----------|-------------| | `CHARGE` | Yes | Process payment immediately | | `TOKENIZE` | Yes | Store card for future use | | `CHARGE_AND_TOKENIZE` | Yes | Process payment and store card | ## 3D Secure 3D Secure is triggered when: - Your CardPay eWallet account is configured to require 3DS, AND - Your PSP integration in Orchestra supports passing 3DS data (see [supported 3DS integrations](https://orchestrasolutions.com/integ-type/3d-secure/)) When both conditions are met, the library handles the entire 3DS challenge flow automatically with no additional code required. See [3D Secure](https://developers.orchestrasolutions.com/guides/library/3d-secure) for more details. ## Related Configure payment processor credentials Parse payment results Authentication details --- # ApplePay URL: https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/apple-pay --- This page is part of **Supported Payment Methods**. [View all payment methods →](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods) Apple Pay enables one-tap payments on Apple devices using Face ID, Touch ID, or passcode authentication. Customers pay with cards stored in their Apple Wallet. ## Availability Apple Pay is only available on Apple devices with Safari browser or in native iOS apps. | Platform | Availability | |----------|--------------| | Safari (macOS) | Yes | | Safari (iOS) | Yes | | Chrome/Firefox/Edge | No | | iOS apps | Yes | | Android | No | ```javascript const available = await engine.checkAvailability(); if (available.includes('ApplePay')) { // Show Apple Pay button } ``` ## Requirements ApplePay requires: - A payment gateway (PSP) account from one of our [supported payment gateways](https://orchestrasolutions.com/integrations/), configured in [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/paymentGateway) - An Apple Developer account with ApplePay enabled (see [ApplePay Setup](https://developers.orchestrasolutions.com/guides/library/applepay-setup)), configured as an ApplePay eWallet account in [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/eWalletAccount) ```javascript // Server-side session creation const session = { operation: 'CHARGE', paymentGatewayAccountId: 'your-psp-account', allowedeWalletAccountIds: ['your-applepay-account'], allowedBrands: ['VISA', 'MASTERCARD', 'AMEX'], amount: 25.00, currencyCode: 'USD', countryCode: 'US', mode: 'LIVE' }; ``` ## Button Setup ```html ``` ```javascript engine.payBy( [{ name: 'ApplePay', domEntitySelector: '#applepay-button' }], handleResult, { color: 'Dark', text: 'Pay' } ); ``` The Apple Pay button renders with Apple's official styling. The `color` and `text` options customize the appearance within Apple's guidelines. ## How It Works 1. Customer clicks the Apple Pay button 2. Apple Pay sheet appears with saved cards 3. Customer selects a card and authenticates with Face ID, Touch ID, or passcode 4. Apple returns encrypted payment data to Orchestra 5. Orchestra processes the payment through your PSP 6. On completion, the popup closes and results are returned to the client, ready to be sent to your server for validation ## Supported Operations | Operation | Supported | Description | |-----------|-----------|-------------| | `CHARGE` | Yes | Process payment immediately | | `TOKENIZE` | Yes | Store payment method for future use | | `CHARGE_AND_TOKENIZE` | Yes | Process payment and store for future | ## 3D Secure All ApplePay transactions are 3DS-enabled. ApplePay uses two-factor authentication (Face ID, Touch ID, or passcode) to verify the cardholder before the transaction is processed. Orchestra automatically passes the 3DS authentication data to your PSP if the [Orchestra integration to your PSP supports 3DS](https://orchestrasolutions.com/integ-type/3d-secure/). ## Address Collection Apple Pay can collect billing and shipping addresses from the customer's Apple Wallet: ```javascript const requiredAncillaryInfo = { billingInfo: { phoneRequired: true, emailAddressRequired: true, details: 'FULL' }, shippingInfo: { phoneRequired: false, emailAddressRequired: false } }; const engine = new eWallet.Engine(sessionToken, requiredAncillaryInfo); ``` ## Related Domain verification and merchant setup Parse payment results --- # GooglePay URL: https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/google-pay --- This page is part of **Supported Payment Methods**. [View all payment methods →](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods) Google Pay enables fast payments using cards stored in the customer's Google account. Available on Android devices and Chrome browser on desktop. ## Availability Google Pay is available on Chrome browsers and Android devices. | Platform | Availability | |----------|--------------| | Chrome (desktop) | Yes | | Chrome (Android) | Yes | | Safari/Firefox/Edge | No | | Android apps | Yes | | iOS | No | ```javascript const available = await engine.checkAvailability(); if (available.includes('GooglePay')) { // Show Google Pay button } ``` ## Requirements GooglePay requires: - A payment gateway (PSP) account from one of our [supported payment gateways](https://orchestrasolutions.com/integrations/), configured in [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/paymentGateway) - A Google Developer account with GooglePay enabled (see [GooglePay Setup](https://developers.orchestrasolutions.com/guides/library/googlepay-setup)), configured as a GooglePay eWallet account in [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/eWalletAccount) ```javascript // Server-side session creation const session = { operation: 'CHARGE', paymentGatewayAccountId: 'your-psp-account', allowedeWalletAccountIds: ['your-googlepay-account'], allowedBrands: ['VISA', 'MASTERCARD', 'AMEX'], amount: 25.00, currencyCode: 'USD', countryCode: 'US', mode: 'LIVE' }; ``` ## Button Setup ```html ``` ```javascript engine.payBy( [{ name: 'GooglePay', domEntitySelector: '#gpay-button' }], handleResult, { color: 'Dark', text: 'Pay' } ); ``` The Google Pay button renders with Google's official styling guidelines. ## How It Works 1. Customer clicks the Google Pay button 2. Google Pay payment sheet appears 3. Customer selects a saved card or adds a new one 4. Customer authenticates (fingerprint, PIN, or password) 5. Google returns encrypted payment data to Orchestra 6. Orchestra processes the payment through your PSP 7. On completion, results are returned to the client, ready to be sent to your server for validation ## Supported Operations | Operation | Supported | Description | |-----------|-----------|-------------| | `CHARGE` | Yes | Process payment immediately | | `TOKENIZE` | Yes | Store payment method for future use | | `CHARGE_AND_TOKENIZE` | Yes | Process payment and store for future | ## 3D Secure GooglePay 3DS support depends on the device: - **Desktop browser**: Not considered 3DS (no two-factor authentication) - **Mobile device**: 3DS-enabled via two-factor authentication (fingerprint, PIN, or password) Orchestra automatically passes the 3DS authentication data to your PSP if the [Orchestra integration to your PSP supports 3DS](https://orchestrasolutions.com/integ-type/3d-secure/). ## Address Collection Google Pay can collect billing and shipping addresses from the customer's Google account: ```javascript const requiredAncillaryInfo = { billingInfo: { phoneRequired: true, emailAddressRequired: true, details: 'FULL' }, shippingInfo: { phoneRequired: false, emailAddressRequired: false } }; const engine = new eWallet.Engine(sessionToken, requiredAncillaryInfo); ``` ## Related Get Google Pay merchant credentials Parse payment results --- # PayPal URL: https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/paypal --- This page is part of **Supported Payment Methods**. [View all payment methods →](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods) PayPal enables customers to pay using their PayPal account balance, linked bank accounts, or saved cards. The payment flow redirects customers to PayPal for authentication. ## Availability PayPal is available on all browsers and devices. | Platform | Availability | |----------|--------------| | Desktop browsers | Yes | | Mobile browsers | Yes | | iOS apps | Yes | | Android apps | Yes | ```javascript const available = await engine.checkAvailability(); if (available.includes('PayPal')) { // Show PayPal button } ``` ## Requirements PayPal requires: - A PayPal Business account (see [PayPal Setup](https://developers.orchestrasolutions.com/guides/library/paypal-setup)), configured as a PayPal eWallet account in [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/eWalletAccount) ```javascript // Server-side session creation const session = { operation: 'CHARGE', paymentGatewayAccountId: 'your-psp-account', allowedeWalletAccountIds: ['your-paypal-account'], allowedBrands: ['VISA', 'MASTERCARD', 'AMEX'], amount: 25.00, currencyCode: 'USD', countryCode: 'US', mode: 'LIVE' }; ``` PayPal does not require a separate PSP account. Payments are processed directly through PayPal. However, `paymentGatewayAccountId` is still required in the session for other payment methods. ## Button Setup ```html ``` ```javascript engine.payBy( [{ name: 'PayPal', domEntitySelector: '#paypal-button' }], handleResult, { color: 'Dark', text: 'Pay' } ); ``` ## How It Works 1. Customer clicks the PayPal button 2. A popup window opens with PayPal login 3. Customer logs into their PayPal account 4. Customer reviews and confirms the payment 5. PayPal redirects back to the popup 6. On completion, the popup closes and results are returned to the client, ready to be sent to your server for validation ## Supported Operations | Operation | Supported | Description | |-----------|-----------|-------------| | `CHARGE` | Yes | Process payment immediately | | `TOKENIZE` | No | Not supported | | `CHARGE_AND_TOKENIZE` | No | Not supported | PayPal only supports immediate charges. Tokenization is not available for PayPal payments. ## Address Collection PayPal can provide the customer's shipping address from their PayPal account: ```javascript const requiredAncillaryInfo = { shippingInfo: { phoneRequired: false, emailAddressRequired: true } }; const engine = new eWallet.Engine(sessionToken, requiredAncillaryInfo); ``` ## Related Configure PayPal credentials Parse payment results --- # BankPay URL: https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/bank-pay --- This page is part of **Supported Payment Methods**. [View all payment methods →](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods) BankPay enables customers to pay directly from their bank account using Open Banking in Europe or ACH in North America. Customers authenticate with their bank to authorize the payment. ## Availability BankPay is available on all browsers and devices, but requires bank support in the payer's region. [Contact our team](https://orchestrasolutions.com/contact/) to confirm if your target region is supported. | Platform | Availability | |----------|--------------| | Desktop browsers | Yes | | Mobile browsers | Yes | | iOS apps | Yes | | Android apps | Yes | ```javascript const available = await engine.checkAvailability(); if (available.includes('BankPay')) { // Show BankPay button } ``` ## Requirements BankPay requires: - An Open Banking or ACH provider account (see [Bank Pay Setup](https://developers.orchestrasolutions.com/guides/library/bankpay-setup)), configured as a BankPay eWallet account in [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/eWalletAccount) ```javascript // Server-side session creation const session = { operation: 'CHARGE', paymentGatewayAccountId: 'your-psp-account', allowedeWalletAccountIds: ['your-bankpay-account'], allowedBrands: ['VISA', 'MASTERCARD', 'AMEX'], amount: 25.00, currencyCode: 'USD', countryCode: 'US', mode: 'LIVE' }; ``` ## Button Setup ```html ``` ```javascript engine.payBy( [{ name: 'BankPay', domEntitySelector: '#bankpay-button' }], handleResult, { color: 'Dark', text: 'Pay' } ); ``` ## How It Works 1. Customer clicks the BankPay button 2. Customer selects their bank from a list 3. Customer is redirected to their bank's authentication page 4. Customer logs in and authorizes the payment 5. Bank redirects back to complete the flow 6. On completion, results are returned to the client, ready to be sent to your server for validation ## Supported Operations | Operation | Supported | Description | |-----------|-----------|-------------| | `CHARGE` | Yes | Process payment immediately | | `TOKENIZE` | No | Not supported | | `CHARGE_AND_TOKENIZE` | No | Not supported | BankPay only supports immediate charges. Tokenization is not available for bank transfers. ## Settlement Time Bank transfers may take longer to settle than card payments: - **Open Banking (Europe)**: Usually instant or same-day - **ACH (US)**: Typically 1-3 business days ## Related Configure Bank Pay credentials Parse payment results --- # UPI URL: https://developers.orchestrasolutions.com/guides/library/supported-payment-methods/upi --- This page is part of **Supported Payment Methods**. [View all payment methods →](https://developers.orchestrasolutions.com/guides/library/supported-payment-methods) UPI (Unified Payments Interface) enables instant bank-to-bank transfers in India. Customers pay using their UPI ID or by scanning a QR code with their UPI app (Google Pay, PhonePe, Paytm, etc.). ## Availability UPI is available on all browsers and devices, but only for transactions in India. | Platform | Availability | |----------|--------------| | Desktop browsers | Yes | | Mobile browsers | Yes | | iOS apps | Yes | | Android apps | Yes | ```javascript const available = await engine.checkAvailability(); if (available.includes('UPI')) { // Show UPI button } ``` UPI is only available for INR transactions with Indian bank accounts. ## Requirements UPI requires: - A UPI provider account (see [UPI Setup](https://developers.orchestrasolutions.com/guides/library/upi-setup)), configured as a UPI eWallet account in [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/eWalletAccount) - Transaction currency must be INR - Customer must have a UPI-enabled bank account in India ```javascript // Server-side session creation const session = { operation: 'CHARGE', paymentGatewayAccountId: 'your-psp-account', allowedeWalletAccountIds: ['your-upi-account'], allowedBrands: ['VISA', 'MASTERCARD', 'AMEX'], amount: 999.00, currencyCode: 'INR', countryCode: 'IN', mode: 'LIVE' }; ``` ## Button Setup ```html ``` ```javascript engine.payBy( [{ name: 'UPI', domEntitySelector: '#upi-button' }], handleResult, { color: 'Dark', text: 'Pay' } ); ``` ## How It Works ### On Mobile 1. Customer clicks the UPI button 2. Customer's UPI app opens (or they choose from installed apps) 3. Customer reviews payment details and enters UPI PIN 4. Payment is processed instantly 5. On completion, results are returned to the client, ready to be sent to your server for validation ### On Desktop 1. Customer clicks the UPI button 2. A QR code is displayed 3. Customer scans the QR code with their UPI app 4. Customer reviews payment details and enters UPI PIN 5. Payment is processed instantly 6. On completion, results are returned to the client, ready to be sent to your server for validation ## Supported Operations | Operation | Supported | Description | |-----------|-----------|-------------| | `CHARGE` | Yes | Process payment immediately | | `TOKENIZE` | No | Not supported | | `CHARGE_AND_TOKENIZE` | No | Not supported | UPI only supports immediate charges. Tokenization is not available for UPI payments. ## Transaction Limits UPI has per-transaction and daily limits set by banks: - **Per transaction**: Typically ₹1,00,000 (varies by bank) - **Daily limit**: Typically ₹1,00,000 - ₹2,00,000 (varies by bank) ## Related Configure UPI credentials Parse payment results --- # Result Handling URL: https://developers.orchestrasolutions.com/guides/library/result-handling --- This page is part of the **Payments Library Guides**. Prefer direct API calls instead? See [REST API Guides](https://developers.orchestrasolutions.com/guides/rest-api/charge). **Prerequisites:** Complete the [Library Setup](https://developers.orchestrasolutions.com/guides/library/setup) first. All payment methods return results through the same callback function. This page covers how to parse results, check for success, and handle different payment types. ## Parsing Results Use `parseResultToken()` to decode the result token: ```javascript function handleResult(result) { // User cancelled if (!result) { console.log('Payment cancelled'); return; } const [data, success] = engine.parseResultToken(result.token); console.log('Payment result:', data); } ``` The method returns a tuple: - `data` - The parsed result object - `success` - Boolean indicating if the token was decoded (not whether payment succeeded) ## Checking Payment Success Always check `clientSuccess` first: ```javascript if (!data.clientSuccess) { console.error('Payment failed:', data.clientErrorMessage); return; } // Payment succeeded - check result type ``` ## Result Types Results vary based on the payment method used: ### PSP Results (CardPay, Apple Pay, Google Pay) Card-based payments return results through `upgChargeResults`: ```javascript if (data.upgChargeResults) { const charge = data.upgChargeResults; if (charge.operationResultCode === 'Success') { console.log('Payment approved'); console.log('Gateway:', charge.gatewayName); console.log('Reference:', charge.gatewayReference); console.log('Auth code:', charge.authorizationCode); console.log('Amount:', charge.amount, charge.currency); } else { console.log('Payment declined:', charge.operationResultDescription); } } ``` **Available fields:** | Field | Description | |-------|-------------| | `gatewayName` | Name of the payment gateway | | `gatewayReference` | Gateway's transaction reference | | `authorizationCode` | Authorization code from issuer | | `amount` | Charged amount | | `currency` | Currency code | | `operationResultCode` | `Success`, `Rejected`, `Error` | | `operationResultDescription` | Human-readable result message | | `gatewayResultDescription` | Message from the gateway | ### Direct Results (PayPal, BankPay, UPI) Redirect-based payments return results through `directChargeResults`: ```javascript if (data.directChargeResults) { if (data.directChargeResults.success) { console.log('Payment successful'); } else { console.log('Payment failed:', data.directChargeResults.message); } } ``` ### Tokenization Results When using `TOKENIZE`, `CHARGE_AND_TOKENIZE`, `PREAUTH_AND_TOKENIZE`, or `GATEWAY_TOKENIZE`, card details are returned in `tokenAndMaskedCardModel`: ```javascript if (data.tokenAndMaskedCardModel) { const tokenData = data.tokenAndMaskedCardModel; console.log('Token:', tokenData.token); console.log('Card type:', tokenData.bankCard.type); console.log('Masked number:', tokenData.bankCard.number); console.log('Expires:', tokenData.bankCard.expirationMonth + '/' + tokenData.bankCard.expirationYear); console.log('Name:', tokenData.bankCard.nameOnCard); } ``` ## Complete Example ```javascript async function handleResult(result) { // User cancelled if (!result) { showMessage('Payment cancelled', 'info'); return; } const [data] = engine.parseResultToken(result.token); // Check overall success if (!data.clientSuccess) { showMessage('Payment failed: ' + data.clientErrorMessage, 'error'); return; } // Handle PSP results (CardPay, Apple Pay, Google Pay) if (data.upgChargeResults) { if (data.upgChargeResults.operationResultCode === 'Success') { showMessage('Payment successful! Reference: ' + data.upgChargeResults.gatewayReference, 'success'); } else { showMessage('Payment declined: ' + data.upgChargeResults.operationResultDescription, 'error'); } } // Handle direct results (PayPal, BankPay, UPI) if (data.directChargeResults) { if (data.directChargeResults.success) { showMessage('Payment successful!', 'success'); } else { showMessage('Payment failed: ' + data.directChargeResults.message, 'error'); } } // Server-side validation (recommended) await validateWithServer(result.token); } ``` ## Server-Side Validation Always validate results on your server before fulfilling orders: ```javascript // Client-side async function validateWithServer(resultToken) { const response = await fetch('/api/validate-payment', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ resultToken }) }); const validation = await response.json(); console.log('Server validation:', validation); } ``` ```javascript // Server-side (Node.js) app.post('/api/validate-payment', async (req, res) => { const { resultToken } = req.body; const response = await fetch('https://api.orchestrasolutions.com/EWalletOperations/validateResults', { method: 'POST', headers: { 'X-Api-Key': process.env.ORCHESTRA_API_KEY, 'Content-Type': 'application/json' }, body: JSON.stringify(resultToken) }); const validationResult = await response.json(); if (validationResult.clientSuccess) { // Payment confirmed - fulfill the order res.json({ success: true }); } else { res.json({ success: false, error: validationResult.clientErrorMessage }); } }); ``` ## Getting Selected Payment Method Use `getSelectedProviderName()` to know which payment method the customer used: ```javascript function handleResult(result) { const provider = engine.getSelectedProviderName(); console.log('Customer paid with:', provider); // "CardPay", "ApplePay", "GooglePay", "PayPal", "BankPay", or "UPI" } ``` ## Related Full API reference End-to-end integration Create a session token Server-side validation endpoint --- # 3D Secure URL: https://developers.orchestrasolutions.com/guides/library/3d-secure --- This page is part of the **Payments Library Guides**. Using the REST API instead? See [REST API 3D Secure](https://developers.orchestrasolutions.com/guides/rest-api/3d-secure). **Prerequisites:** Complete the [Library Setup](https://developers.orchestrasolutions.com/guides/library/setup) with a [3DS-capable PSP](https://orchestrasolutions.com/integ-type/3d-secure/). 3D Secure (3DS) adds an authentication step during card payments. The Payments Library handles 3DS challenges automatically. No additional code required. For general setup instructions, see [Library Setup](https://developers.orchestrasolutions.com/guides/library/setup). ## How It Works 1. Card form opens 2. Customer enters card details 3. Library detects 3DS requirement based on CardPay eWallet specification and PSP integration status 4. Authentication challenge displays (popup or iframe) 5. Customer completes verification (password, SMS code, biometric, or app confirmation) 6. Orchestra completes the requested operation 7. On completion, the transaction results, including the 3DS data, are returned to the client, ready to be sent to your server for validation The library handles the entire flow automatically. ## When to Trigger 3DS? You may want to use 3D Secure on your transactions in any of the following use cases: | Use Case | Description | |----------|-------------| | Card issuer requirement | Bank requires authentication for this card/amount | | Regional regulations | PSD2/SCA in Europe, similar rules in other regions | | Transaction amount | High-value transactions often require 3DS | | Risk assessment | Issuer flags transaction as requiring verification | | Gateway configuration | Your PSP settings may require 3DS | We recommend using 3DS to authenticate all transactions, even when not required. 3DS provides merchants with liability shift protection and peace of mind knowing that the payer has been fully and properly authenticated. ## Supported Payment Methods | Method | 3DS Support | |--------|-------------| | CardPay | Yes (automatically by Orchestra) | | ApplePay | Yes (automatically by ApplePay) | | GooglePay | Partial, depending on device type (automatically by GooglePay) | | PayPal | N/A (uses own authentication) | | BankPay | N/A (uses bank authentication) | | UPI | N/A | ## 3DS Data in Results After successful 3DS authentication and completion of the transaction, the result includes authentication data in `tokenAndMaskedCardModel.threeDs`: ```javascript const [data] = engine.parseResultToken(result.token); if (data.tokenAndMaskedCardModel?.threeDs) { const tds = data.tokenAndMaskedCardModel.threeDs; console.log('Version:', tds.version); // "2.1.0", "2.2.0", etc. console.log('ECI:', tds.eci); // Electronic Commerce Indicator console.log('Auth value:', tds.authenticationValue); // CAVV/AAV console.log('XID:', tds.xid); // Transaction ID console.log('SLI:', tds.sli); // Service Level Indicator (Mastercard) } ``` ### ThreeDS Fields | Field | Description | |-------|-------------| | `version` | 3DS protocol version (e.g., "2.1.0", "2.2.0") | | `eci` | Electronic Commerce Indicator - liability shift indicator | | `authenticationValue` | Cardholder Authentication Verification Value (CAVV/AAV) | | `xid` | Transaction identifier | | `sli` | Service Level Indicator (Mastercard only) | ### ECI Values The ECI indicates the authentication result and liability: | ECI | Visa/Amex | Mastercard | Meaning | |-----|-----------|------------|---------| | 05 | 02 | Fully authenticated | Liability shift to issuer | | 06 | 01 | Attempted (issuer not enrolled) | Liability shift to issuer | | 07 | 00 | Not authenticated | No liability shift | ## Handling 3DS Failures If 3DS authentication fails, the payment will not complete. The callback receives a result with `clientSuccess: false`: ```javascript function handleResult(result) { if (!result) { // User cancelled return; } const [data] = engine.parseResultToken(result.token); if (!data.clientSuccess) { // Payment failed - could be 3DS failure console.error('Payment failed:', data.clientErrorMessage); return; } // Payment successful } ``` ## PSP Requirements 3DS requires a payment processor that supports 3DS connections. Not all PSPs support 3DS for all card types. See the [list of integrations that support 3DS](https://orchestrasolutions.com/integ-type/3d-secure/). When configuring your PSP in Orchestra, ensure: 1. PSP supports 3DS (check with your provider) 2. 3DS credentials are configured in your PSP account 3. `threeDsAccountName` is set when creating sessions (if using a separate 3DS provider) ```javascript // Server-side session creation with 3DS account const session = { operation: 'CHARGE', amount: 100.00, currencyCode: 'USD', mode: 'LIVE', paymentGatewayAccountId: 'your-psp', threeDsAccountName: 'your-3ds-account' // Optional: if using separate 3DS provider }; ``` ## Frictionless vs. Challenge Flow 3DS 2.x supports two flows: | Flow | Description | User Experience | |------|-------------|-----------------| | Frictionless | Risk-based authentication passes silently | No interruption | | Challenge | User must complete verification | Popup/redirect | The library handles both flows automatically. Frictionless authentication completes without user interaction when the issuer's risk assessment allows it. ## Related CardPay, ApplePay, GooglePay, PayPal, BankPay, UPI Parse and validate payment results Full API reference Configure payment processor --- # Charge Payments URL: https://developers.orchestrasolutions.com/guides/rest-api/charge --- This page is part of the **REST API Guides**. Using the JavaScript library instead? See [Payments Library Guides](https://developers.orchestrasolutions.com/guides/library/setup). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key) and [Payment Gateway Account](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) configured. The charge operation captures funds from a card immediately. Use this for standard purchases where you're ready to fulfill the order. Some payment processors require additional parameters. See the [Additional Guidance](https://developers.orchestrasolutions.com/guides/rest-api/gateway-requirements) section for processor-specific requirements. ## Basic Charge ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ amount: 25.00, currency: 'USD', paymentGatewayAccountName: 'stripe-production', card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); const result = await response.json(); ``` ```bash cURL curl -X POST https://api.orchestrasolutions.com/PaymentGateway/charge \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "amount": 25.00, "currency": "USD", "paymentGatewayAccountName": "stripe-production", "card": { "cardNumber": "4111111111111111", "cardHolderName": "Jane Smith", "expirationMonth": 12, "expirationYear": 2027, "cvv": "123" } }' ``` ```python Python response = requests.post( 'https://api.orchestrasolutions.com/PaymentGateway/charge', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'amount': 25.00, 'currency': 'USD', 'paymentGatewayAccountName': 'stripe-production', 'card': { 'cardNumber': '4111111111111111', 'cardHolderName': 'Jane Smith', 'expirationMonth': 12, 'expirationYear': 2027, 'cvv': '123' } } ) ``` Complete parameter reference, response fields, and validation rules To use a tokenized card number, prefix the token with `@` in the `cardNumber` field: `"cardNumber": "@your-token-id"`. See [Tokenization](https://developers.orchestrasolutions.com/guides/rest-api/tokenization). ## Using a Stored Token If you've tokenized a card number with [StringTokens](https://developers.orchestrasolutions.com/guides/rest-api/tokenization), reference it in the `cardNumber` field with an `@` prefix: ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ amount: 25.00, currency: 'USD', paymentGatewayAccountName: 'stripe-production', card: { cardNumber: '@nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO', // Token with @ prefix cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` ## Using Inline Credentials Instead of a stored Payment Gateway Account, you can provide credentials inline: ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ amount: 25.00, currency: 'USD', paymentGatewayAccount: { paymentGatewayName: 'Stripe', credentials: [ { Key: 'SecretKey', Value: 'sk_live_...' } ] }, card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` ## Adding Failover To automatically try backup gateways if the primary fails, add a `fallbackUpgs` array: ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ amount: 25.00, currency: 'USD', paymentGatewayAccountName: 'stripe-production', fallbackUpgs: [ { paymentGatewayAccountName: 'adyen-backup' }, { paymentGatewayAccountName: 'worldpay-tertiary' } ], card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` See [Multi-Gateway Failover](https://developers.orchestrasolutions.com/guides/rest-api/multi-gateway-failover) for the full guide. ## Charge vs Authorize | Operation | When to Use | |-----------|-------------| | **Charge** | Immediate fulfillment, digital goods, services | | **Authorize** | Delayed fulfillment, physical goods, variable amounts | If you need to hold funds without capturing immediately, use [Authorize & Capture](https://developers.orchestrasolutions.com/guides/rest-api/authorize-capture) instead. ## Related Reverse or cancel this charge Hold funds and capture later Store card numbers securely --- # Multi-Gateway Failover URL: https://developers.orchestrasolutions.com/guides/rest-api/multi-gateway-failover --- This page is part of the **REST API Guides**. Using the JavaScript library instead? See [Payments Library Guides](https://developers.orchestrasolutions.com/guides/library/setup). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key) and multiple [Payment Gateway Accounts](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) configured. Multi-gateway failover is Orchestra's core value proposition: if one payment provider fails or is unavailable, Orchestra automatically tries the next provider in your list until one succeeds. ## Why Use Multi-Gateway Failover Without Orchestra, a provider outage means lost transactions. With multi-gateway failover, your payment flow stays resilient: - **Provider downtime** - If Stripe is down, transactions automatically route to Adyen - **Regional issues** - Network problems in one region don't affect your entire payment flow - **Rate limiting** - Exceed limits on one provider, overflow to another - **Business continuity** - Maintain high payment availability ## How It Works Add a `fallbackUpgs` array to your charge or authorize request. Each entry specifies a backup Payment Gateway Account to try if the primary fails: ```json { "paymentGatewayAccountName": "stripe-production", "fallbackUpgs": [ { "paymentGatewayAccountName": "adyen-production" }, { "paymentGatewayAccountName": "checkout-production" } ], "amount": 25.00, "currency": "USD", "card": { ... } } ``` Orchestra sends the transaction to the primary gateway (`paymentGatewayAccountName`). If it fails with a recoverable error, Orchestra tries each fallback in order until one succeeds. ## Basic Example ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ paymentGatewayAccountName: 'stripe-production', fallbackUpgs: [ { paymentGatewayAccountName: 'adyen-backup' }, { paymentGatewayAccountName: 'worldpay-tertiary' } ], amount: 25.00, currency: 'USD', card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); const result = await response.json(); ``` ```bash cURL curl -X POST https://api.orchestrasolutions.com/PaymentGateway/charge \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "paymentGatewayAccountName": "stripe-production", "fallbackUpgs": [ { "paymentGatewayAccountName": "adyen-backup" }, { "paymentGatewayAccountName": "worldpay-tertiary" } ], "amount": 25.00, "currency": "USD", "card": { "cardNumber": "4111111111111111", "cardHolderName": "Jane Smith", "expirationMonth": 12, "expirationYear": 2027, "cvv": "123" } }' ``` ```python Python response = requests.post( 'https://api.orchestrasolutions.com/PaymentGateway/charge', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'paymentGatewayAccountName': 'stripe-production', 'fallbackUpgs': [ {'paymentGatewayAccountName': 'adyen-backup'}, {'paymentGatewayAccountName': 'worldpay-tertiary'} ], 'amount': 25.00, 'currency': 'USD', 'card': { 'cardNumber': '4111111111111111', 'cardHolderName': 'Jane Smith', 'expirationMonth': 12, 'expirationYear': 2027, 'cvv': '123' } } ) ``` ## The `fallbackUpgs` Array Each entry in the `fallbackUpgs` array has these fields: | Field | Type | Required | Description | |-------|------|----------|-------------| | `paymentGatewayAccountName` | string | Yes | The name of the backup Payment Gateway Account | | `paymentGatewayCertName` | string | No | Client certificate name, if the gateway requires one | ## Failover Logic Orchestra tries each gateway in order: 1. **Primary attempt** - Transaction sent to the gateway specified in `paymentGatewayAccountName` 2. **Check result** - If successful, return immediately 3. **Evaluate failure** - If the failure is recoverable, try the next gateway in `fallbackUpgs` 4. **Repeat** - Continue until success or all gateways exhausted 5. **Final result** - Return success from the first working gateway, or the last failure ### What Triggers Failover Orchestra attempts the next gateway when the primary fails with a **recoverable** error: - Gateway returns an error response (500, 503) - Gateway is unreachable (network timeout) - Gateway temporarily rejects the transaction ### What Doesn't Trigger Failover Orchestra does NOT fail over when the failure is **non-recoverable**: - Card declined by the issuing bank (legitimate decline) - Invalid card number or CVV - Card expired These are payment failures, not gateway failures - the card would be declined on any provider. ## Works With Charge and Authorize The `fallbackUpgs` parameter is available on both operations: - **Charge** (`POST /PaymentGateway/charge`) - Immediate payment with failover - **Authorize** (`POST /PaymentGateway/authorize`) - Authorization hold with failover ### Authorize with Failover ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/authorize', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ paymentGatewayAccountName: 'stripe-production', fallbackUpgs: [ { paymentGatewayAccountName: 'adyen-backup' } ], amount: 50.00, currency: 'USD', card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` When using failover with authorize, the response tells you which gateway processed the transaction. Use the same gateway for the subsequent capture, void, or refund. ## Configuration Strategies ### Primary + Backup Most common setup: one primary provider, one backup for emergencies. ```json { "paymentGatewayAccountName": "stripe-production", "fallbackUpgs": [ { "paymentGatewayAccountName": "adyen-backup" } ] } ``` ### Geographic Routing with Failover Combine [BIN-based routing](https://developers.orchestrasolutions.com/guides/rest-api/utilities/card-tools/metadata-lookup) with failover. Use the card's issuer country to pick the primary gateway, and add regional backups: ```javascript const { countryCode } = await getCardMetadata(cardBin); const request = { amount: 25.00, currency: 'USD', card: { ... } }; if (countryCode === 'MA') { request.paymentGatewayAccountName = 'payzone-morocco'; request.fallbackUpgs = [ { paymentGatewayAccountName: 'stripe-global' } ]; } else { request.paymentGatewayAccountName = 'stripe-global'; request.fallbackUpgs = [ { paymentGatewayAccountName: 'adyen-global' }, { paymentGatewayAccountName: 'checkout-global' } ]; } ``` ### With Client Certificates Some gateways require client certificates. Use `paymentGatewayCertName` in the fallback entry: ```json { "paymentGatewayAccountName": "stripe-production", "fallbackUpgs": [ { "paymentGatewayAccountName": "gateway-with-cert", "paymentGatewayCertName": "my-client-cert" } ] } ``` ## Response The response includes which gateway processed the transaction. Use the `gatewayName` field to identify which provider succeeded: ```json { "operationType": "Charge", "operationResultCode": "Success", "gatewayName": "Adyen", "gatewayReference": "txn_abc123", "amount": 25.00, "currency": "USD" } ``` Track which gateway succeeded to help with: - Cost analysis per provider - Performance monitoring - Ensuring subsequent operations (capture, void, refund) go to the correct gateway ## Testing Failover Test your failover configuration using mock gateways. See [Mock PSPs](https://developers.orchestrasolutions.com/guides/utilities/mock-psps) for setup details. ## Best Practices List fallback gateways in order of preference - lowest cost or best performance first. Track which gateways are being used. High failover rates indicate issues with the primary. Verify failover works by simulating primary gateway failures in sandbox. Use providers with strong presence in your target markets as primary for those regions. ## Related Understanding Orchestra's architecture Configure multiple providers Basic charge operation Get card issuer country for BIN-based routing --- # 3D Secure Authentication URL: https://developers.orchestrasolutions.com/guides/rest-api/3d-secure --- This page is part of the **REST API Guides**. Using the JavaScript library instead? See [Payments Library 3D Secure](https://developers.orchestrasolutions.com/guides/library/3d-secure). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key), [Payment Gateway Account](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) with a [3DS-capable gateway](https://orchestrasolutions.com/integ-type/3d-secure/), and a 3DS authentication provider. 3D Secure (3DS) is an authentication protocol that adds an extra layer of security for online card transactions. It helps reduce fraud and liability by verifying the cardholder's identity before completing the payment. ## Passing 3DS Authentication Data to PSPs Many of Orchestra's PSP integrations support receiving 3DS authentication data. If you have already performed 3DS authentication for a card (using your own 3DS provider or a third-party service), you can pass those authentication results to Orchestra when making a charge request. For a complete list of PSP integrations that support 3DS data, see [3D Secure Integrations](https://orchestrasolutions.com/integ-type/3d-secure/). ### 3DS Authentication Fields When you have 3DS authentication results, include them in the `threeDSAuthentication` object within the card details: | Field | Description | |-------|-------------| | `authenticationValue` | The cryptographic authentication value (CAVV for Visa, AAV for Mastercard) | | `eci` | Electronic Commerce Indicator - indicates the outcome of the 3DS authentication | | `xid` | Transaction identifier from the 3DS authentication | | `version` | The 3DS protocol version used (e.g., "2.1.0", "2.2.0") | | `merchantName` | The merchant name used during 3DS authentication | | `sli` | Security Level Indicator | ### Example: Charge with 3DS Data Here's an example of a charge request that includes 3DS authentication results: ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ paymentGatewayAccountName: 'your-gateway-account', amount: 25.00, currency: 'USD', myRef: 'PaymentX112358', card: { cardType: 'Visa', cardHolderName: 'Jane Smith', cardNumber: '4111111111111111', expirationMonth: 12, expirationYear: 2027, cvv: '123', threeDSAuthentication: { authenticationValue: 'AJkBABkhYQAAAABVYCFhAAAAAAA=', eci: '05', xid: 'MDAwMDAwMDAwMDAwMDAwMDAwMDE=', version: '2.2.0', merchantName: 'Your Merchant Name', sli: '02' } } }) }); const result = await response.json(); ``` ```bash cURL curl -X POST https://api.orchestrasolutions.com/PaymentGateway/charge \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "paymentGatewayAccountName": "your-gateway-account", "amount": 25.00, "currency": "USD", "myRef": "PaymentX112358", "card": { "cardType": "Visa", "cardHolderName": "Jane Smith", "cardNumber": "4111111111111111", "expirationMonth": 12, "expirationYear": 2027, "cvv": "123", "threeDSAuthentication": { "authenticationValue": "AJkBABkhYQAAAABVYCFhAAAAAAA=", "eci": "05", "xid": "MDAwMDAwMDAwMDAwMDAwMDAwMDE=", "version": "2.2.0", "merchantName": "Your Merchant Name", "sli": "02" } } }' ``` ```python Python response = requests.post( 'https://api.orchestrasolutions.com/PaymentGateway/charge', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'paymentGatewayAccountName': 'your-gateway-account', 'amount': 25.00, 'currency': 'USD', 'myRef': 'PaymentX112358', 'card': { 'cardType': 'Visa', 'cardHolderName': 'Jane Smith', 'cardNumber': '4111111111111111', 'expirationMonth': 12, 'expirationYear': 2027, 'cvv': '123', 'threeDSAuthentication': { 'authenticationValue': 'AJkBABkhYQAAAABVYCFhAAAAAAA=', 'eci': '05', 'xid': 'MDAwMDAwMDAwMDAwMDAwMDAwMDE=', 'version': '2.2.0', 'merchantName': 'Your Merchant Name', 'sli': '02' } } } ) ``` You can also use a tokenized card number (e.g., `"@xxxxxxxxxxxxxxxx"`) instead of the raw card number when passing 3DS data. See [Tokenization](https://developers.orchestrasolutions.com/guides/rest-api/tokenization). ## What's Next Basic charge operations Hold funds and capture later --- # Transaction Status URL: https://developers.orchestrasolutions.com/guides/rest-api/transaction-status --- This page is part of the **REST API Guides**. Using the JavaScript library instead? See [Payments Library Guides](https://developers.orchestrasolutions.com/guides/library/setup). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key), [Payment Gateway Account](https://developers.orchestrasolutions.com/getting-started/add-payment-provider), and an existing transaction ID. Query the status of a previously submitted charge or authorization. Useful for reconciliation and handling timeout scenarios. **Endpoint**: `POST /PaymentGateway/status` ## Check by Transaction ID Look up a transaction using the gateway's transaction ID (returned from charge/authorize): ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/status', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ refTransId: 'txn_abc123', paymentGatewayAccountName: 'stripe-production' }) }); const result = await response.json(); ``` ```bash cURL curl -X POST https://api.orchestrasolutions.com/PaymentGateway/status \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "refTransId": "txn_abc123", "paymentGatewayAccountName": "stripe-production" }' ``` ```python Python response = requests.post( 'https://api.orchestrasolutions.com/PaymentGateway/status', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'refTransId': 'txn_abc123', 'paymentGatewayAccountName': 'stripe-production' } ) ``` ## Check by Your Reference Look up a transaction using your custom reference (`myRef` from the original request): ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/status', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ myRef: 'order-12345', paymentGatewayAccountName: 'stripe-production' }) }); ``` Using `myRef` requires that you passed a custom reference when creating the original transaction. Complete parameter reference for status requests ## Response ```json { "operationType": "Status", "operationResultCode": "Success", "operationResultDescription": "Transaction found", "gatewayName": "Stripe", "gatewayReference": "txn_abc123", "gatewayResultCode": "succeeded", "gatewayResultDescription": "Payment completed", "amount": 25.00, "currency": "USD" } ``` ## Use Cases ### Handling Timeouts If a charge request times out, check the status before retrying to avoid duplicate charges: ```javascript async function chargeWithRetry(chargeData) { try { const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ ...chargeData, myRef: `order-${Date.now()}` // Always include a reference }), signal: AbortSignal.timeout(30000) }); return await response.json(); } catch (error) { if (error.name === 'TimeoutError') { // Check if the transaction went through const status = await fetch('https://api.orchestrasolutions.com/PaymentGateway/status', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ myRef: chargeData.myRef, paymentGatewayAccountName: chargeData.paymentGatewayAccountName }) }); return await status.json(); } throw error; } } ``` ### Daily Reconciliation Verify transaction statuses against your records: ```javascript async function verifyTransaction(transactionId, gatewayAccount) { const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/status', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ refTransId: transactionId, paymentGatewayAccountName: gatewayAccount }) }); const result = await response.json(); return { found: result.operationResultCode === 'Success', status: result.gatewayResultCode, amount: result.amount }; } ``` ## Related Cancel or reverse transactions --- # Authorize & Capture URL: https://developers.orchestrasolutions.com/guides/rest-api/authorize-capture --- This page is part of the **REST API Guides**. Using the JavaScript library instead? See [Payments Library Guides](https://developers.orchestrasolutions.com/guides/library/setup). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key) and [Payment Gateway Account](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) configured. Authorization places a hold on funds without capturing them immediately. Use capture, void, or refund to complete the transaction lifecycle. Some payment processors require additional parameters. See the [Additional Guidance](https://developers.orchestrasolutions.com/guides/rest-api/gateway-requirements) section for processor-specific requirements. ## When to Use Authorize - **Physical goods**: Authorize at checkout, capture when shipped - **Variable amounts**: Authorize an estimate, capture the actual amount - **Verification**: Confirm a card is valid before providing a service - **Hotels/rentals**: Authorize a hold, capture the final bill ## Authorize ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/authorize', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ amount: 50.00, currency: 'USD', paymentGatewayAccountName: 'stripe-production', card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); const result = await response.json(); // Save the transaction ID for capture/void/refund ``` ```bash cURL curl -X POST https://api.orchestrasolutions.com/PaymentGateway/authorize \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "amount": 50.00, "currency": "USD", "paymentGatewayAccountName": "stripe-production", "card": { "cardNumber": "4111111111111111", "cardHolderName": "Jane Smith", "expirationMonth": 12, "expirationYear": 2027, "cvv": "123" } }' ``` ```python Python response = requests.post( 'https://api.orchestrasolutions.com/PaymentGateway/authorize', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'amount': 50.00, 'currency': 'USD', 'paymentGatewayAccountName': 'stripe-production', 'card': { 'cardNumber': '4111111111111111', 'cardHolderName': 'Jane Smith', 'expirationMonth': 12, 'expirationYear': 2027, 'cvv': '123' } } ) ``` Complete parameter reference for authorize requests Save the transaction ID from the response. You'll need it for capture, void, or refund operations. ### Authorize with Failover To automatically try backup gateways if the primary fails, add a `fallbackUpgs` array: ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/authorize', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ amount: 50.00, currency: 'USD', paymentGatewayAccountName: 'stripe-production', fallbackUpgs: [ { paymentGatewayAccountName: 'adyen-backup' } ], card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` When using failover with authorize, check which gateway processed the transaction in the response. Use the same gateway for the subsequent capture, void, or refund. See [Multi-Gateway Failover](https://developers.orchestrasolutions.com/guides/rest-api/multi-gateway-failover) for the full guide. --- ## Capture Capture an existing authorization to complete the transaction. Uses **PUT** method. Capture requires re-sending the `currency`, `card`, and other details from the original authorization. ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/capture', { method: 'PUT', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ refTransId: 'original-transaction-id', amount: 45.00, currency: 'USD', paymentGatewayAccountName: 'stripe-production', card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` ```bash cURL curl -X PUT https://api.orchestrasolutions.com/PaymentGateway/capture \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "refTransId": "original-transaction-id", "amount": 45.00, "currency": "USD", "paymentGatewayAccountName": "stripe-production", "card": { "cardNumber": "4111111111111111", "cardHolderName": "Jane Smith", "expirationMonth": 12, "expirationYear": 2027, "cvv": "123" } }' ``` ```python Python response = requests.put( 'https://api.orchestrasolutions.com/PaymentGateway/capture', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'refTransId': 'original-transaction-id', 'amount': 45.00, 'currency': 'USD', 'paymentGatewayAccountName': 'stripe-production', 'card': { 'cardNumber': '4111111111111111', 'cardHolderName': 'Jane Smith', 'expirationMonth': 12, 'expirationYear': 2027, 'cvv': '123' } } ) ``` Complete parameter reference for capture requests --- ## Completing the Transaction After authorizing, you have three options: | Action | When to Use | |--------|-------------| | **Capture** | Ready to fulfill - collect the funds | | **Void** | Cancel before capture - release the hold | | **Refund** | Return funds after capture | For void and refund operations, see [Refunds & Voids](https://developers.orchestrasolutions.com/guides/rest-api/refunds-voids). --- ## Authorization Expiration Authorizations expire if not captured (typically 7-30 days depending on card network). After expiration, the hold is released and you'll need a new authorization. Don't rely on authorization expiration to release holds. If you're not going to capture, void the authorization explicitly. ## Related Cancel or reverse transactions --- # Refunds & Voids URL: https://developers.orchestrasolutions.com/guides/rest-api/refunds-voids --- This page is part of the **REST API Guides**. Using the JavaScript library instead? See [Payments Library Guides](https://developers.orchestrasolutions.com/guides/library/setup). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key), [Payment Gateway Account](https://developers.orchestrasolutions.com/getting-started/add-payment-provider), and an existing transaction to refund or void. Use void to cancel an authorization before capture, or refund to return funds after a transaction has been captured. ## When to Use Each | Operation | Use When | |-----------|----------| | **Void** | Cancel an authorization before capturing funds | | **Refund** | Return funds after a charge or capture has completed | Voids release the hold on the customer's card immediately. Refunds may take 5-10 business days to appear on the customer's statement. ## Void Cancel an authorization before capturing. Uses **DELETE** method. Void requires re-sending the `currency`, `amount`, `card`, and other details from the original authorization. ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/void', { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ refTransId: 'original-transaction-id', amount: 50.00, currency: 'USD', paymentGatewayAccountName: 'stripe-production', card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` ```bash cURL curl -X DELETE https://api.orchestrasolutions.com/PaymentGateway/void \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "refTransId": "original-transaction-id", "amount": 50.00, "currency": "USD", "paymentGatewayAccountName": "stripe-production", "card": { "cardNumber": "4111111111111111", "cardHolderName": "Jane Smith", "expirationMonth": 12, "expirationYear": 2027, "cvv": "123" } }' ``` ```python Python response = requests.delete( 'https://api.orchestrasolutions.com/PaymentGateway/void', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'refTransId': 'original-transaction-id', 'amount': 50.00, 'currency': 'USD', 'paymentGatewayAccountName': 'stripe-production', 'card': { 'cardNumber': '4111111111111111', 'cardHolderName': 'Jane Smith', 'expirationMonth': 12, 'expirationYear': 2027, 'cvv': '123' } } ) ``` Complete parameter reference for void requests --- ## Refund Refund a captured transaction. Uses **PUT** method. ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/refund', { method: 'PUT', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ refTransId: 'original-transaction-id', amount: 25.00, currency: 'USD', paymentGatewayAccountName: 'stripe-production', card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` ```bash cURL curl -X PUT https://api.orchestrasolutions.com/PaymentGateway/refund \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "refTransId": "original-transaction-id", "amount": 25.00, "currency": "USD", "paymentGatewayAccountName": "stripe-production", "card": { "cardNumber": "4111111111111111", "cardHolderName": "Jane Smith", "expirationMonth": 12, "expirationYear": 2027, "cvv": "123" } }' ``` ```python Python response = requests.put( 'https://api.orchestrasolutions.com/PaymentGateway/refund', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'refTransId': 'original-transaction-id', 'amount': 25.00, 'currency': 'USD', 'paymentGatewayAccountName': 'stripe-production', 'card': { 'cardNumber': '4111111111111111', 'cardHolderName': 'Jane Smith', 'expirationMonth': 12, 'expirationYear': 2027, 'cvv': '123' } } ) ``` Complete parameter reference for refund requests ### Partial Refunds You can refund less than the original amount: ```javascript // Original charge was $100.00 // Refund only $25.00 const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/refund', { method: 'PUT', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ refTransId: 'original-transaction-id', amount: 25.00, // Partial refund currency: 'USD', paymentGatewayAccountName: 'stripe-production', card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` --- ## Related Full transaction lifecycle Check refund status --- # Tokenization URL: https://developers.orchestrasolutions.com/guides/rest-api/tokenization --- This page is part of the **REST API Guides**. Using the JavaScript library instead? See [Payments Library Guides](https://developers.orchestrasolutions.com/guides/library/setup). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key) configured. The StringTokens service lets you tokenize and store any sensitive string: card numbers, full card details as JSON, addresses, or any data up to 16,384 characters. The token can then be used in place of the raw data in subsequent API calls. **PCI Compliance**: If you store card details and later retrieve them, your system is exposed to raw card data and is in scope for PCI compliance. Consider using tokens only for storage and referencing them in payment requests without retrieval. ## Why Tokenize - **Security**: Sensitive data stays in Orchestra's vault, not your systems - **Compliance**: Reduces PCI scope when storing card numbers - **Flexibility**: Store any string data (card numbers, JSON, addresses) **Security Best Practice**: Store each piece of sensitive data in its own individual token rather than combining multiple values into a single token. For example, create separate tokens for the card PAN, CVV, and cardholder ID. This approach limits exposure if a token is compromised and provides more granular control over data access and lifecycle management. ## Create a Token Store a string and receive a token reference. **Endpoint**: `POST /StringTokens` ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/StringTokens', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ payload: '4111111111111111' }) }); const result = await response.json(); // result.token = 'nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO' ``` ```bash cURL curl -X POST https://api.orchestrasolutions.com/StringTokens \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "payload": "4111111111111111" }' ``` ```python Python response = requests.post( 'https://api.orchestrasolutions.com/StringTokens', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'payload': '4111111111111111' } ) ``` Complete parameter reference and response fields --- ## Retrieve Token Contents Retrieve the original string stored behind a token. **Endpoint**: `GET /StringTokens/{token}` Retrieving token contents exposes your system to the raw data. If you stored card details, this puts you in scope for PCI compliance. ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/StringTokens/nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO', { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }); const result = await response.json(); // result.payload = '4111111111111111' ``` ```bash cURL curl https://api.orchestrasolutions.com/StringTokens/nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO \ -H "X-Api-Key: YOUR_API_KEY" ``` ```python Python response = requests.get( 'https://api.orchestrasolutions.com/StringTokens/nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO', headers={ 'X-Api-Key': 'YOUR_API_KEY' } ) ``` --- ## Retrieve Token Metadata Get metadata about a token without retrieving the actual contents. **Endpoint**: `GET /StringTokens/{token}/meta` ```javascript const response = await fetch('https://api.orchestrasolutions.com/StringTokens/nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO/meta', { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }); ``` --- ## Delete a Token Permanently delete a stored token. **Endpoint**: `DELETE /StringTokens/{token}` Deletion cannot be undone. Once deleted, the token and its contents are permanently removed. ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/StringTokens/nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY' } }); ``` ```bash cURL curl -X DELETE https://api.orchestrasolutions.com/StringTokens/nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO \ -H "X-Api-Key: YOUR_API_KEY" ``` ```python Python response = requests.delete( 'https://api.orchestrasolutions.com/StringTokens/nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO', headers={ 'X-Api-Key': 'YOUR_API_KEY' } ) ``` --- ## Using Tokens with Payment Gateway Reference a token in the `cardNumber` field with an `@` prefix when making payment requests: ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ amount: 25.00, currency: 'USD', paymentGatewayAccountName: 'stripe-production', card: { cardNumber: '@nQGywsQE9gbURtrXEjTZwtWqeMdK9nsO', // Token with @ prefix cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); ``` The payment gateway retrieves the card number from the token automatically. Your system never sees the raw card number. The `@` prefix tells Orchestra to look up the token value. Without it, the string is treated as a literal card number. ## Storing Full Card Details You can store any string, including JSON-stringified card details: ```javascript const cardDetails = JSON.stringify({ cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027 }); const response = await fetch('https://api.orchestrasolutions.com/StringTokens', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ payload: cardDetails }) }); ``` ## Related Use tokens in payment requests Full endpoint documentation --- # Gateway Tokenization URL: https://developers.orchestrasolutions.com/guides/rest-api/gateway-tokenization --- This page is part of the **REST API Guides**. Using the JavaScript library instead? See [Payments Library Guides](https://developers.orchestrasolutions.com/guides/library/setup). **Prerequisites:** [API key](https://developers.orchestrasolutions.com/getting-started/generate-api-key) and [Payment Gateway Account](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) with a gateway that supports tokenization. Gateway tokenization creates a token stored directly with your payment processor (Stripe, Adyen, etc.) for recurring billing. This is different from [String Tokenization](https://developers.orchestrasolutions.com/guides/rest-api/tokenization), which stores data in Orchestra's vault. Not all payment gateways support tokenization. For a complete list of integrations that support gateway tokenization, see [Gateway Token Integrations](https://orchestrasolutions.com/integ-type/gateway-token/). You can also check your gateway's capabilities programmatically using the [List Gateways](https://developers.orchestrasolutions.com/guides/rest-api/utilities/list-gateways) endpoint. ## When to Use Gateway Tokens | Use Case | Solution | |----------|----------| | Recurring subscriptions | Gateway tokenization | | Stored cards for returning customers | Gateway tokenization | | Temporary storage during checkout | [String Tokenization](https://developers.orchestrasolutions.com/guides/rest-api/tokenization) | | PCI scope reduction (any data) | [String Tokenization](https://developers.orchestrasolutions.com/guides/rest-api/tokenization) | ## Create a Gateway Token **Endpoint**: `POST /PaymentGateway/tokenize` ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/tokenize', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ paymentGatewayAccountName: 'stripe-production', card: { cardNumber: '4111111111111111', cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027, cvv: '123' } }) }); const result = await response.json(); // result.gatewayToken contains the processor-specific token ``` ```bash cURL curl -X POST https://api.orchestrasolutions.com/PaymentGateway/tokenize \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "paymentGatewayAccountName": "stripe-production", "card": { "cardNumber": "4111111111111111", "cardHolderName": "Jane Smith", "expirationMonth": 12, "expirationYear": 2027, "cvv": "123" } }' ``` ```python Python response = requests.post( 'https://api.orchestrasolutions.com/PaymentGateway/tokenize', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'paymentGatewayAccountName': 'stripe-production', 'card': { 'cardNumber': '4111111111111111', 'cardHolderName': 'Jane Smith', 'expirationMonth': 12, 'expirationYear': 2027, 'cvv': '123' } } ) ``` Complete parameter reference for tokenization requests ### Response ```json { "operationType": "Tokenize", "operationResultCode": "Success", "operationResultDescription": "Token created", "gatewayName": "Stripe", "gatewayToken": "tok_1abc123...", "gatewayResultCode": "approved", "gatewayResultDescription": "Token created successfully" } ``` The `gatewayToken` value is the processor-specific token you'll use for future charges. ## Using Gateway Tokens Once you have a gateway token, use it with the `userToken` parameter in charge or authorize requests: ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway/charge', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ amount: 29.99, currency: 'USD', paymentGatewayAccountName: 'stripe-production', userToken: 'tok_1abc123...', // Gateway token from tokenize card: { cardNumber: '4111111111111111', // Can be masked/placeholder cardHolderName: 'Jane Smith', expirationMonth: 12, expirationYear: 2027 } }) }); ``` ## Gateway Token vs String Token | Feature | Gateway Token | String Token | |---------|---------------|--------------| | Storage location | Payment processor | Orchestra vault | | Use case | Recurring billing | PCI scope reduction | | Portability | Tied to one gateway | Works across gateways | | Data type | Card details only | Any string (up to 16KB) | ## Related Store any data in Orchestra's vault Use tokens in payment requests --- # Gateway-Specific Requirements URL: https://developers.orchestrasolutions.com/guides/rest-api/gateway-requirements --- This page is part of the **REST API Guides**. Using the JavaScript library instead? See [Payments Library Guides](https://developers.orchestrasolutions.com/guides/library/setup). Some payment gateways require additional parameters or have unique configuration requirements. This page documents gateway-specific details you may need when integrating. These requirements apply when using the REST API directly. The Payments Library handles most of these automatically. ## Adyen The `ShopperInteraction` parameter specifies the sales channel and whether the customer is returning. ```json { "paymentGatewayAccount": { "paymentGatewayName": "Adyen", "credentials": [ { "Key": "ApiKey", "Value": "..." }, { "Key": "MerchantAccount", "Value": "..." }, { "Key": "ShopperInteraction", "Value": "Ecommerce" } ] } } ``` For POS accounts, set `ShopperInteraction` to `"Ecommerce"`. --- ## AMEX The `myRef` parameter is **required** and must contain 6 or more characters. ```json { "myRef": "ORDER123456" } ``` --- ## Authorize.net The `ECCenabled` parameter controls refund behavior: | Value | Behavior | |-------|----------| | `true` | Full card details sent with refund requests | | `false` | Refunds not possible after 120 days from original charge | ```json { "paymentGatewayAccount": { "paymentGatewayName": "AuthorizeNet", "credentials": [ { "Key": "ApiLoginId", "Value": "..." }, { "Key": "TransactionKey", "Value": "..." }, { "Key": "ECCenabled", "Value": "true" } ] } } ``` --- ## Cardstream Cardstream uses the `OrderDesc` parameter to provide additional order description. ```json { "orderDesc": "Premium subscription - 12 months" } ``` --- ## Caterpay Caterpay uses the `OrderDesc` parameter to provide additional order description. ```json { "orderDesc": "Premium subscription - 12 months" } ``` --- ## Credorax Credorax requires integration certification. Orchestra's integration is certified with Credorax. Contact [support@orchestrasolutions.com](mailto:support@orchestrasolutions.com) if you need certification documentation. --- ## Elavon Include the `RebatePWD` (rebate password) in your credentials: ```json { "paymentGatewayAccount": { "paymentGatewayName": "Elavon", "credentials": [ { "Key": "MerchantId", "Value": "..." }, { "Key": "Password", "Value": "..." }, { "Key": "RebatePWD", "Value": "your_rebate_password" } ] } } ``` --- ## First Data (FirstDataIPG) First Data requires: 1. **Client certificate authentication** - [Upload your certificate](https://portal.orchestrasolutions.com/#/resource/certificates/create) through the Orchestra Portal 2. **Client IP address** - Provide in the `PayerDetails` object ```json { "payerDetails": { "clientIPAddress": "192.168.1.1" }, "certificateName": "your-uploaded-certificate-name" } ``` --- ## Gateline Gateline has the same requirements as First Data: 1. **Client certificate authentication** - [Upload via portal](https://portal.orchestrasolutions.com/#/resource/certificates/create) 2. **Client IP address** - Required in `PayerDetails` ```json { "payerDetails": { "clientIPAddress": "192.168.1.1" }, "certificateName": "your-uploaded-certificate-name" } ``` --- ## Global Payments WebPay The `myRef` parameter must be a **15-digit numeric value**. ```json { "myRef": "123456789012345" } ``` --- ## Heartland Heartland has two requirements: 1. **`myRef` must be numeric only** (no letters or special characters) 2. **Integration certification required** - Orchestra's integration is certified ```json { "myRef": "123456789" } ``` --- ## Kortapay The `OriginalAmount` parameter is **mandatory** for Void and Refund operations. ```json { "refTransId": "original-transaction-id", "amount": 25.00, "originalAmount": 25.00 } ``` --- ## PayGate Your PayGate merchant account must have the **"auto-settle" flag set to "off"**. Configure this in your PayGate merchant dashboard before integrating. --- ## Pesopay Pesopay has two requirements: 1. **`myRef` must be unique** on every submission 2. **Void operations** must use the `GatewayReference` from the PreAuth response, not Capture ```json { "myRef": "UNIQUE-REF-20240115-001" } ``` --- ## Stripe (PaymentIntent) ### 3D Secure Support To enable 3DS transactions, contact Stripe and request enabling the `payment_method_options.card.request_three_d_secure` option on your account. ### Subscriptions Use the `SetupFutureUsage` parameter to enable Stripe Subscriptions: ```json { "paymentGatewayAccount": { "paymentGatewayName": "StripePaymentIntent", "credentials": [ { "Key": "SecretKey", "Value": "sk_live_..." }, { "Key": "SetupFutureUsage", "Value": "off_session" } ] } } ``` | Value | Use Case | |-------|----------| | `on_session` | Customer present during future charges | | `off_session` | Recurring/subscription charges without customer | --- ## Wirecard Wirecard uses the `OrderDesc` parameter to provide additional order description. ```json { "orderDesc": "Premium subscription - 12 months" } ``` --- ## Worldpay Worldpay has two requirements: 1. **`IsDigital` parameter** - Required, defaults to `true` 2. **Integration certification required** - Orchestra's integration is certified ```json { "isDigital": true } ``` --- ## Zeamster Zeamster uses the `OrderDesc` parameter to provide additional order description. ```json { "orderDesc": "Premium subscription - 12 months" } ``` --- ## Zoop Use the `NoOfInstallments` parameter to split payments into installments (micro credit): ```json { "noOfInstallments": 6 } ``` | Value | Description | |-------|-------------| | 1-12 | Number of monthly installments | --- ## Related Full endpoint documentation Configure gateway credentials --- # Mock Payment Gateways URL: https://developers.orchestrasolutions.com/guides/utilities/mock-psps --- This page applies to both the [REST API](https://developers.orchestrasolutions.com/guides/rest-api/charge) and [Payments Library](https://developers.orchestrasolutions.com/guides/library/setup). Orchestra provides two mock payment gateways for testing: **NULLSuccess** always approves transactions, **NULLFailure** always declines them. This lets you test both success and failure handling in your integration without external accounts. ## What Are Mock PSPs? Mock PSPs are static responders that return the same response every time, regardless of card number, amount, or other transaction details: - **NULLSuccess** - Always returns successful approval - **NULLFailure** - Always returns decline/failure This predictability lets you reliably test both code paths in your integration. No actual payment processing occurs - mock PSPs simply return instant, static responses so you can verify your application handles success and failure correctly. **Key characteristics:** - Available by default to all Orchestra accounts - Require no credentials or configuration - Return instant responses (no network latency) - Accept any card data, amount, or transaction details - Return responses in the same format as real PSPs **Use mock PSPs when:** - Building initial integration (getting started) - Testing success/failure handling logic - Running automated tests in CI/CD - Demonstrating payment flows without real credentials - Testing Apple Pay and Google Pay integrations - Testing with network tokens **Use real provider sandboxes when:** - Testing 3D Secure authentication with the Payments Library - Testing specific decline codes or error scenarios - Testing gateway tokenization - Validating gateway-specific features (fraud tools, installments, etc.) - Preparing for production deployment ## Available Mock Gateways | Gateway Name | Behavior | Use Case | |--------------|----------|----------| | `NULLSuccess` | Always approves transactions | Test happy path logic | | `NULLFailure` | Always declines transactions | Test error handling | ## Setup See the [Quickstart](https://developers.orchestrasolutions.com/quickstart) for step-by-step instructions on creating mock gateway accounts in the Portal. ## Usage Use mock PSPs the same way as real payment gateways - reference the account name in your API calls. See the [Quickstart](https://developers.orchestrasolutions.com/quickstart) for complete REST API and Payments Library examples. ## Supported Operations Mock PSPs support the following payment operations: - **Charge** - Returns instant success or failure - **Authorize/Capture** - Returns instant success or failure - **Refund** - Returns instant success or failure - **Void** - Returns instant success or failure All operations return instant, static responses. The response you receive depends solely on which mock gateway you use (NULLSuccess or NULLFailure), not on the transaction details you submit. Mock PSPs do not support gateway tokenization operations. To test gateway tokenization, use a real PSP sandbox account. ## Response Format Mock PSPs return responses in the same format as real PSPs, with mock data populated in all fields. This allows you to build and test your response handling logic before connecting to real payment providers. **Example NULLSuccess response:** ```json { "authorizationCode": "fbbb8b", "currency": "USD", "amount": 2.56, "operationType": "Charge", "operationResultCode": "Success", "operationResultDescription": "Successful operation", "gatewayName": "NULLSuccess", "gatewayReference": "b362db", "gatewayResultCode": "OK", "gatewayResultDescription": "Gateway says: Successful operation", "gatewayResultSubCode": null, "gatewayResultSubDescription": null } ``` ## Digital Wallets (Apple Pay & Google Pay) Mock PSPs fully support Apple Pay and Google Pay testing. When Orchestra receives an encrypted wallet payload, it extracts the virtual card details and sends them to the PSP as a regular card transaction. Since mock PSPs accept any card data, wallet transactions work seamlessly. ## Network Tokens Mock PSPs accept network tokens without any special handling. Network tokens use the standard PAN format, so they're processed the same as regular card numbers. ## 3D Secure Behavior How 3DS works with mock PSPs depends on whether you're using the REST API or the Payments Library: ### REST API With the REST API, you handle 3DS authentication externally and pass the authentication results to Orchestra inline with the card details. Mock PSPs accept this 3DS data and respond with their static response (success or failure). This allows you to test your 3DS data handling logic. ### Payments Library With the Payments Library, 3DS authentication is triggered at the point of card entry. Whether 3DS is attempted depends on: 1. The customer has enabled 3DS in their CardPay eWallet configuration 2. The PSP integration supports passing 3DS data **The mock PSP integration does not support passing 3DS data.** Therefore, when using the Payments Library with a mock PSP, 3DS authentication will not be triggered, even if the customer has 3DS enabled. To test 3DS flows with the Payments Library, use a real PSP sandbox account that supports 3DS. See [3D Secure Integrations](https://orchestrasolutions.com/integ-type/3d-secure/) for a complete list of supported PSPs. ## Limitations Mock PSPs are designed for integration testing. They have several limitations compared to real payment provider sandboxes: ### Static Responses Only Mock PSPs return predetermined success or failure responses regardless of input. They cannot simulate specific decline codes or error scenarios. However, you can use them to: - Verify your system handles success correctly (NULLSuccess) - Verify your system handles failure correctly (NULLFailure) - Design decision trees based on the consistent error format returned ### Gateway Tokenization Mock PSPs do not support gateway tokenization operations. To test creating and using gateway tokens, use a real PSP sandbox account. ### Gateway-Specific Features PSP-specific functionality (fraud tools, installments, recurring billing setup, etc.) is not available with mock PSPs. ## Test Data Mock PSPs accept any card data: test cards, real card numbers, any amount, any expiration date, any CVV. The response depends only on which gateway you use (NULLSuccess or NULLFailure), not on the transaction details. This means you can use whatever test data is convenient for your development workflow. ## Graduating to Real Providers When you're ready to process real transactions, [add a payment provider](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) to Orchestra, then change the gateway account name in your API calls: ```javascript // Before (mock) paymentGatewayAccountName: 'test-success' // After (real provider) paymentGatewayAccountName: 'your-provider-name' ``` Everything else in your code stays the same. ## Best Practices Use mock PSPs for initial development. They're instant and require no external accounts. Switch to real provider sandboxes before production to catch integration issues. Never use mock PSPs in production. They don't process real transactions. Use mock PSPs in CI/CD pipelines for fast, reliable test runs. ## Related Get started with mock PSPs in 5 minutes Connect real gateways Sandbox vs production environments Manage gateway accounts programmatically --- # Validate API Key URL: https://developers.orchestrasolutions.com/guides/rest-api/utilities/validate-api-key --- This page is part of the **REST API Guides**. [View all REST API guides →](https://developers.orchestrasolutions.com/guides/rest-api/charge) Quick health check: verify your API key is valid and Orchestra is reachable with a single GET request. Use this before troubleshooting integration issues. Validate that your API key is correctly configured and the Orchestra API is reachable. **Endpoint**: `GET /Utils/apiKey` ## Validate Your Key ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/Utils/apiKey', { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }); if (response.ok) { const result = await response.json(); console.log('API key valid:', result); } else { console.error('Invalid API key'); } ``` ```bash cURL curl https://api.orchestrasolutions.com/Utils/apiKey \ -H "X-Api-Key: YOUR_API_KEY" ``` ```python Python response = requests.get( 'https://api.orchestrasolutions.com/Utils/apiKey', headers={ 'X-Api-Key': 'YOUR_API_KEY' } ) if response.status_code == 200: print('API key valid:', response.json()) else: print('Invalid API key') ``` Complete response fields and status codes ## Use Cases ### Health Check Include in your application's startup or health check routine: ```javascript async function checkOrchestraConnection() { try { const response = await fetch('https://api.orchestrasolutions.com/Utils/apiKey', { headers: { 'X-Api-Key': process.env.ORCHESTRA_API_KEY } }); if (!response.ok) { throw new Error('Invalid Orchestra API key'); } const { isSandbox } = await response.json(); console.log(`Orchestra connected (${isSandbox ? 'sandbox' : 'production'})`); return true; } catch (error) { console.error('Orchestra connection failed:', error.message); return false; } } ``` ### Environment Verification Confirm you're using the correct key for your environment: ```javascript const result = await response.json(); if (process.env.NODE_ENV === 'production' && result.isSandbox) { console.warn('Warning: Using sandbox API key in production!'); } ``` ## Related Create a new API key Sandbox vs production --- # List Supported Gateways URL: https://developers.orchestrasolutions.com/guides/rest-api/utilities/list-gateways --- This page is part of the **REST API Guides**. [View all REST API guides →](https://developers.orchestrasolutions.com/guides/rest-api/charge) Discover all {supportedIntegrations} payment gateways Orchestra supports and see exactly what credentials each requires. No need to search documentation or contact support. Retrieve the list of all payment gateways integrated with Orchestra, along with the credentials each requires. **Endpoint**: `GET /PaymentGateway` ## List All Gateways ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGateway', { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }); const gateways = await response.json(); ``` ```bash cURL curl https://api.orchestrasolutions.com/PaymentGateway \ -H "X-Api-Key: YOUR_API_KEY" ``` ```python Python response = requests.get( 'https://api.orchestrasolutions.com/PaymentGateway', headers={ 'X-Api-Key': 'YOUR_API_KEY' } ) gateways = response.json() ``` Complete response fields and status codes ## Using Gateway Information ### Find Required Credentials Before adding a payment provider, check what credentials you need: ```javascript const gateways = await response.json(); const stripe = gateways.find(g => g.name === 'Stripe'); console.log('Required credentials:', stripe.credentialsNames); // ['SecretKey'] ``` ### Create Gateway Account with Correct Credentials Use the `credentialsNames` to structure your [Gateway Account](https://developers.orchestrasolutions.com/guides/rest-api/utilities/gateway-accounts) request: ```javascript // For a gateway requiring ['ApiKey', 'MerchantAccount'] const accountData = { paymentGatewayName: 'Adyen', credentials: [ { Key: 'ApiKey', Value: 'your-api-key' }, { Key: 'MerchantAccount', Value: 'your-merchant-account' } ] }; ``` ### Check Network Token Support For card scheme network tokens (Visa, Mastercard, Amex): ```javascript const gateways = await response.json(); const networkTokenGateways = gateways.filter(g => g.supportsNetworkToken); console.log('Gateways supporting network tokens:'); networkTokenGateways.forEach(g => console.log(`- ${g.displayName}`)); ``` ## Related Store gateway credentials Portal-based setup --- # Gateway Accounts URL: https://developers.orchestrasolutions.com/guides/rest-api/utilities/gateway-accounts --- This page is part of the **REST API Guides**. [View all REST API guides →](https://developers.orchestrasolutions.com/guides/rest-api/charge) Automate gateway credential management: create, update, and delete payment gateway accounts programmatically instead of using the Portal UI. Ideal for CI/CD pipelines and multi-environment deployments. Payment Gateway Accounts store your processor credentials securely in Orchestra. While most users configure these through the [Portal](https://developers.orchestrasolutions.com/getting-started/add-payment-provider), you can also manage them programmatically. Account names must be 3-64 alphanumeric characters (no spaces or special characters). ## Create or Update an Account **Endpoint**: `PUT /PaymentGatewayAccounts/{name}` ```javascript Node.js const response = await fetch('https://api.orchestrasolutions.com/PaymentGatewayAccounts/stripe-production', { method: 'PUT', headers: { 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, body: JSON.stringify({ paymentGatewayName: 'Stripe', credentials: [ { Key: 'SecretKey', Value: 'sk_live_...' } ] }) }); ``` ```bash cURL curl -X PUT https://api.orchestrasolutions.com/PaymentGatewayAccounts/stripe-production \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -d '{ "paymentGatewayName": "Stripe", "credentials": [ { "Key": "SecretKey", "Value": "sk_live_..." } ] }' ``` ```python Python response = requests.put( 'https://api.orchestrasolutions.com/PaymentGatewayAccounts/stripe-production', headers={ 'Content-Type': 'application/json', 'X-Api-Key': 'YOUR_API_KEY' }, json={ 'paymentGatewayName': 'Stripe', 'credentials': [ {'Key': 'SecretKey', 'Value': 'sk_live_...'} ] } ) ``` Complete parameter reference, response fields, and status codes for all operations ### Finding Required Credentials Each gateway requires different credentials. Use [List Gateways](https://developers.orchestrasolutions.com/guides/rest-api/utilities/list-gateways) to find the `credentialsNames` for your gateway: ```javascript // GET /PaymentGateway returns: // { "name": "Adyen", "credentialsNames": ["ApiKey", "MerchantAccount"] } // So your credentials array should include: { "paymentGatewayName": "Adyen", "credentials": [ { "Key": "ApiKey", "Value": "your-api-key" }, { "Key": "MerchantAccount", "Value": "your-merchant-account" } ] } ``` --- ## Retrieve an Account **Endpoint**: `GET /PaymentGatewayAccounts/{name}` ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGatewayAccounts/stripe-production', { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }); const account = await response.json(); ``` --- ## List All Accounts **Endpoint**: `GET /PaymentGatewayAccounts` ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGatewayAccounts', { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }); const accounts = await response.json(); ``` The list endpoint returns brief information without credentials. Use the retrieve endpoint to get full details. --- ## Delete an Account **Endpoint**: `DELETE /PaymentGatewayAccounts/{name}` ```javascript const response = await fetch('https://api.orchestrasolutions.com/PaymentGatewayAccounts/old-account', { method: 'DELETE', headers: { 'X-Api-Key': 'YOUR_API_KEY' } }); ``` Deletion is permanent. Ensure no active integrations reference the account before deleting. --- ## Naming Conventions Suggested naming patterns for gateway accounts: | Pattern | Example | Use Case | |---------|---------|----------| | `{gateway}-{environment}` | `stripe-production` | Single gateway per environment | | `{gateway}-{region}` | `adyen-eu` | Regional gateway routing | | `{gateway}-{channel}` | `stripe-web`, `stripe-mobile` | Channel-specific accounts | ## Related Find required credentials UI-based configuration --- # Card Tools URL: https://developers.orchestrasolutions.com/guides/rest-api/utilities/card-tools --- The Card Tools are a set of utility endpoints that let you work with card BIN/IIN data. The BIN (Bank Identification Number), also known as IIN (Issuer Identification Number), is the first 6 to 11 digits of a card number. These digits identify the card's brand, issuing bank, country of origin, and card type. All Card Tools endpoints are authenticated with your API key. Both the input (the first 6-11 digits of the card number) and the output are considered non-sensitive data - the BIN/IIN alone cannot identify a cardholder or be used to initiate a transaction, so calling these endpoints does not put you in PCI scope. ## Available Tools Identify the card brand (Visa, Mastercard, etc.) and get a logo URL to display in your UI. Get the full card metadata: brand, type (credit/debit), category, issuing bank, and country of issue. Validate a full card number using the Luhn algorithm, with optional metadata in the response. Assess transaction risk by comparing card origin against the payer's IP address and billing country. ## Authentication All Card Tools endpoints require an API key passed in the `X-Api-Key` header. See [Generate API Key](https://developers.orchestrasolutions.com/getting-started/generate-api-key) to get started. --- # Brand Lookup URL: https://developers.orchestrasolutions.com/guides/rest-api/utilities/card-tools/brand-lookup --- The Brand Lookup endpoint identifies the card brand (Visa, Mastercard, American Express, etc.) from the card's BIN/IIN and returns a URL to the brand's logo image. **Endpoint:** `GET /Tools/brand` ## When to Use This Use Brand Lookup when you need to display the card brand logo in your payment form as the customer types their card number. After the customer enters the first 6 digits, you can call this endpoint to identify the brand and show the corresponding logo - giving the customer immediate visual feedback that their card is recognized. This is lighter than the full [Metadata Lookup](https://developers.orchestrasolutions.com/guides/rest-api/utilities/card-tools/metadata-lookup) since it only returns the brand name and logo URL. ## How It Works Pass the first 6 to 11 digits of the card number as the `iin` query parameter. The endpoint returns the identified brand and a URL to the brand's logo. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `iin` | string (query) | Yes | The first 6 to 11 digits of the card number | ## Example: Show Brand Logo During Card Entry Call the endpoint once the customer has entered at least 6 digits, then display the logo next to the card number field. ```javascript Node.js const cardInput = document.getElementById('card-number'); cardInput.addEventListener('input', async (e) => { const digits = e.target.value.replace(/\D/g, ''); if (digits.length >= 6) { const response = await fetch( `https://api.orchestrasolutions.com/Tools/brand?iin=${digits.substring(0, 8)}`, { headers: { 'X-Api-Key': 'YOUR_API_KEY' } } ); if (response.ok) { const { brand, brandLogoUrl } = await response.json(); document.getElementById('brand-logo').src = brandLogoUrl; document.getElementById('brand-logo').alt = brand; } } }); ``` ```python Python def get_brand(card_digits, api_key): """Identify the card brand from the first 6-11 digits.""" response = requests.get( 'https://api.orchestrasolutions.com/Tools/brand', params={'iin': card_digits[:8]}, headers={'X-Api-Key': api_key} ) response.raise_for_status() data = response.json() return data['brand'], data['brandLogoUrl'] brand, logo_url = get_brand('41111111', 'YOUR_API_KEY') print(f"Brand: {brand}") # "VISA" print(f"Logo: {logo_url}") ``` ```bash cURL curl "https://api.orchestrasolutions.com/Tools/brand?iin=411111" \ -H "X-Api-Key: YOUR_API_KEY" ``` ## Related Need more than just the brand? Get full card metadata. Full endpoint specification and response schema --- # Metadata Lookup URL: https://developers.orchestrasolutions.com/guides/rest-api/utilities/card-tools/metadata-lookup --- The Metadata Lookup endpoint returns the full metadata for a card based on its BIN/IIN. This includes the card brand, type (credit/debit), category, issuing organization, country of issue, and a brand logo URL. **Endpoint:** `GET /Tools/iin` ## When to Use This Use Metadata Lookup when you need detailed card information to make decisions before processing a payment. The most common use case is **BIN-based routing** - directing transactions to different payment gateways based on the card's issuer country, brand, or type. For example, a travel company operating across regions might route cards issued in Morocco through a local PSP (e.g., Payzone) for better approval rates, while routing all other cards through a global PSP (e.g., Stripe). ## How It Works Pass the first 6 to 11 digits of the card number as the `iin` query parameter. The endpoint returns the full metadata record for that BIN range. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `iin` | string (query) | Yes | The first 6 to 11 digits of the card number | ### Response Fields | Field | Description | |-------|-------------| | `bin` | The matched BIN prefix (6-11 digits) | | `cardBrand` | Card brand (VISA, MASTERCARD, AMERICAN EXPRESS, JCB, etc.) | | `cardType` | Card type (CREDIT, DEBIT, DEBIT OR CREDIT, CHARGE CARD) | | `category` | Card category (CLASSIC, GOLD, PLATINUM, BUSINESS, etc.) | | `issuingOrganization` | Name of the issuing bank | | `countryCode` | ISO 3166-2 two-letter country code of the issuer | | `brandLogoUrl` | URL to the brand logo image | ## Example: BIN-Based Payment Routing Route payments to different PSPs based on the card's issuer country to optimize approval rates and processing costs. ```javascript Node.js async function selectGateway(cardNumber, apiKey) { const iin = cardNumber.replace(/\D/g, '').substring(0, 8); const response = await fetch( `https://api.orchestrasolutions.com/Tools/iin?iin=${iin}`, { headers: { 'X-Api-Key': apiKey } } ); const { countryCode, cardBrand } = await response.json(); // Route Moroccan cards to a local PSP for better approval rates if (countryCode === 'MA') { return 'payzone-morocco'; } // Route Amex through a gateway with better Amex rates if (cardBrand === 'AMERICAN EXPRESS') { return 'amex-preferred-gateway'; } return 'stripe-default'; } ``` ```python Python def select_gateway(card_number, api_key): """Choose the best PSP based on card metadata.""" iin = card_number.replace(' ', '')[:8] response = requests.get( 'https://api.orchestrasolutions.com/Tools/iin', params={'iin': iin}, headers={'X-Api-Key': api_key} ) response.raise_for_status() meta = response.json() if meta['countryCode'] == 'MA': return 'payzone-morocco' if meta['cardBrand'] == 'AMERICAN EXPRESS': return 'amex-preferred-gateway' return 'stripe-default' ``` ```bash cURL curl "https://api.orchestrasolutions.com/Tools/iin?iin=411111" \ -H "X-Api-Key: YOUR_API_KEY" # Response: # { # "bin": "411111", # "cardBrand": "VISA", # "cardType": "CREDIT", # "category": "CLASSIC", # "issuingOrganization": "JPMORGAN CHASE BANK, N.A.", # "countryCode": "US", # "brandLogoUrl": "https://..." # } ``` ## Related Only need the brand? Use the lighter Brand Lookup endpoint. Combine BIN routing with gateway failover for maximum reliability. --- # Luhn Validation URL: https://developers.orchestrasolutions.com/guides/rest-api/utilities/card-tools/luhn-validation --- The Luhn Validation endpoint checks whether a card number is valid according to the [Luhn algorithm](https://en.wikipedia.org/wiki/Luhn_algorithm) - the standard checksum formula used by all major card schemes. Optionally, you can request the card's metadata in the same call. **Endpoint:** `GET /Tools/luhn` ## When to Use This Use Luhn Validation as an early check before submitting a payment. A card number that fails the Luhn check is guaranteed to be invalid - catching it here avoids an unnecessary API call to the PSP, saves processing time, and gives the customer immediate feedback to correct their input. By setting `metaData=true`, you can combine validation and metadata lookup in a single call - useful when you need both the validity check and card details (e.g., for form validation plus BIN-based routing in one step). ## How It Works Pass the full card number as the `number` query parameter. Set `metaData` to `true` if you also want the card's BIN metadata in the response. | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `number` | string (query) | Yes | The full card number to validate | | `metaData` | boolean (query) | No | Include card metadata in the response (default: `false`) | ## Example: Validate Before Payment Submission Check the card number on your server before sending it to the PSP. If validation fails, return an error to the customer immediately. ```javascript Node.js async function validateCard(cardNumber, apiKey) { const response = await fetch( `https://api.orchestrasolutions.com/Tools/luhn?number=${cardNumber}&metaData=true`, { headers: { 'X-Api-Key': apiKey } } ); const result = await response.json(); if (!result.luhnValid) { return { valid: false, error: result.error || 'Invalid card number' }; } return { valid: true, brand: result.iinData?.cardBrand, type: result.iinData?.cardType, issuerCountry: result.iinData?.countryCode }; } const check = await validateCard('4111111111111111', 'YOUR_API_KEY'); if (!check.valid) { console.error(check.error); } else { console.log(`Valid ${check.brand} ${check.type} card from ${check.issuerCountry}`); } ``` ```python Python def validate_card(card_number, api_key): """Validate card number and return metadata if valid.""" response = requests.get( 'https://api.orchestrasolutions.com/Tools/luhn', params={'number': card_number, 'metaData': 'true'}, headers={'X-Api-Key': api_key} ) response.raise_for_status() result = response.json() if not result['luhnValid']: raise ValueError(result.get('error', 'Invalid card number')) iin = result.get('iinData', {}) return { 'brand': iin.get('cardBrand'), 'type': iin.get('cardType'), 'country': iin.get('countryCode'), } try: info = validate_card('4111111111111111', 'YOUR_API_KEY') print(f"Valid {info['brand']} {info['type']} card from {info['country']}") except ValueError as e: print(f"Invalid card: {e}") ``` ```bash cURL # Validate with metadata curl "https://api.orchestrasolutions.com/Tools/luhn?number=4111111111111111&metaData=true" \ -H "X-Api-Key: YOUR_API_KEY" # Validate only (no metadata) curl "https://api.orchestrasolutions.com/Tools/luhn?number=4111111111111111" \ -H "X-Api-Key: YOUR_API_KEY" ``` ## Related Already know the card is valid? Look up metadata from just the BIN. Full endpoint specification and response schema --- # Card Validation URL: https://developers.orchestrasolutions.com/guides/rest-api/utilities/card-tools/card-validation --- The Card Validation endpoint performs a risk assessment by comparing the card's BIN metadata (issuer country) against the payer's billing address and IP geolocation. It returns a risk level along with the full card metadata and the detected countries from each data source. **Endpoint:** `POST /Tools/validate` ## When to Use This Use Card Validation as a pre-transaction fraud screening step. By comparing where the card was issued, where the payer claims to be (billing address), and where they actually are (IP geolocation), you can flag suspicious transactions before they reach the PSP. For example, a card issued in Germany being used from an IP address in Nigeria with a billing address in the US would produce a high risk score - an indication that the transaction warrants additional scrutiny or rejection. ## How It Works Pass the card's BIN/IIN as a query parameter and the payer's billing details in the request body. **Query parameter:** | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `iin` | string | Yes | The first 6 to 11 digits of the card number | **Request body:** | Field | Type | Required | Description | |-------|------|----------|-------------| | `clientIPAddress` | string | Yes | The payer's IP address | | `countryCode` | string | Yes | ISO 3166-2 two-letter country code from billing address | | `city` | string | No | Billing city | | `stateProvince` | string | No | Billing state or province | ### Risk Levels | Level | Meaning | |-------|---------| | `VeryLow` | Card issuer country, IP country, and billing country all match | | `Low` | Minor discrepancy between data points | | `High` | Significant mismatch between card origin and payer location | | `VeryHigh` | Multiple mismatches or anonymous proxy detected | ## Example: Pre-Transaction Fraud Check Screen transactions before processing and flag high-risk payments for manual review. ```javascript Node.js async function assessRisk(cardBin, payerInfo, apiKey) { const response = await fetch( `https://api.orchestrasolutions.com/Tools/validate?iin=${cardBin}`, { method: 'POST', headers: { 'X-Api-Key': apiKey, 'Content-Type': 'application/json' }, body: JSON.stringify({ clientIPAddress: payerInfo.ip, countryCode: payerInfo.country, city: payerInfo.city, stateProvince: payerInfo.state }) } ); const result = await response.json(); if (result.riskLevel === 'VeryHigh' || result.riskLevel === 'High') { console.warn(`High risk: ${result.description}`); console.warn(`Card from ${result.issuerCountry}, IP from ${result.countryByIP}, billing from ${result.countryFromBillingAddress}`); if (result.anonymousProxyUsed) { console.warn('Anonymous proxy detected'); } return { approved: false, reason: result.description }; } return { approved: true, riskLevel: result.riskLevel }; } const risk = await assessRisk('411111', { ip: '203.0.113.42', country: 'US', city: 'New York', state: 'NY' }, 'YOUR_API_KEY'); ``` ```python Python def assess_risk(card_bin, payer_ip, payer_country, api_key, city=None, state=None): """Assess transaction risk based on card origin vs payer location.""" response = requests.post( 'https://api.orchestrasolutions.com/Tools/validate', params={'iin': card_bin}, headers={ 'X-Api-Key': api_key, 'Content-Type': 'application/json' }, json={ 'clientIPAddress': payer_ip, 'countryCode': payer_country, 'city': city, 'stateProvince': state } ) response.raise_for_status() result = response.json() if result['riskLevel'] in ('High', 'VeryHigh'): print(f"WARNING: {result['description']}") print(f" Card issuer: {result['issuerCountry']}") print(f" IP location: {result['countryByIP']}") print(f" Billing: {result['countryFromBillingAddress']}") print(f" Proxy: {result['anonymousProxyUsed']}") return False return True is_safe = assess_risk('411111', '203.0.113.42', 'US', 'YOUR_API_KEY', city='New York', state='NY') ``` ```bash cURL curl -X POST "https://api.orchestrasolutions.com/Tools/validate?iin=411111" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "clientIPAddress": "203.0.113.42", "countryCode": "US", "city": "New York", "stateProvince": "NY" }' ``` ## Related Get card metadata without the risk assessment Full endpoint specification and response schema --- # Google Pay Setup URL: https://developers.orchestrasolutions.com/guides/library/googlepay-setup --- This page is part of **Merchant Account Setup**. [Back to Library Setup →](https://developers.orchestrasolutions.com/guides/library/setup) Google Pay collects payment credentials from customers. You'll also need a [payment provider configured](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) in Orchestra to process the transactions. ## 1. Create a Business Profile 1. Go to the [Google Pay & Wallet Console](https://pay.google.com/business/console/) 2. Sign in with your Google account 3. Complete the business profile setup ## 2. Register Your Website 1. Add your website in the console 2. Select your integration type 3. Submit for approval ## 3. Get Your Merchant ID After Google approves your integration, you'll receive a **Merchant ID**, a unique identifier for your business. This is required for production. You can test without a Merchant ID using Google's test environment. The Merchant ID is only required for production. ## 4. Store in Orchestra [Store your Merchant ID](https://developers.orchestrasolutions.com/guides/library/store-merchant-account) in the Orchestra Portal. Set the **merchantName** (your business name shown to customers during payment). ## Next Steps Save your Google Pay credentials in Orchestra Implement Google Pay in your integration --- # Apple Pay Setup URL: https://developers.orchestrasolutions.com/guides/library/applepay-setup --- This page is part of **Merchant Account Setup**. [Back to Library Setup →](https://developers.orchestrasolutions.com/guides/library/setup) Apple Pay collects payment credentials from customers. You'll also need a [payment provider configured](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) in Orchestra to process the transactions. **Requires:** [Apple Developer Program](https://developer.apple.com/programs/) membership ($99/year) To generate the required data for an Apple Pay eWallet Account, follow the steps below to create and configure your Merchant ID, certificates, and domain verification. ## 1. Create a Merchant ID A Merchant ID identifies you as a merchant who is able to accept payments via Apple Pay. 1. Sign in to your [Apple Developer Account](https://developer.apple.com/account/) 2. Go to **Certificates, Identifiers & Profiles** > **Identifiers** 3. Click **+** to add a new identifier 4. Select **Merchant IDs** 5. Enter a **description** and a **unique identifier** for your Merchant ID (e.g., `merchant.com.example.yourbusiness`) 6. Click **Continue**, review the details, and then **Register** ## 2. Verify Merchant Domain Apple requires your domain to be verified to ensure that only authorized domains can initiate Apple Pay transactions on behalf of your Merchant ID. 1. Go back to the **Merchant ID** page in the developer portal 2. Under your Merchant ID, click **Edit** and then **Verify Your Domain** 3. Enter the domain name you want to use for Apple Pay (e.g., `example.com`) 4. Download the **Apple Pay Verification File** (`apple-developer-merchantid-domain-association`) 5. Upload the file to the `.well-known` directory on your domain. The full URL should be: `https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association` 6. Return to the Apple Developer Portal and click **Verify**. If the file is hosted correctly, the domain will be verified. The file must be served over HTTPS without redirects. Download the file only once. Repeated downloads generate new content. Domain verification is required for Apple Pay to function. Without it, the Apple Pay button will appear but the payment sheet will close immediately when clicked. ## 3. Create Payment Processing Certificate This certificate is used by your payment processor to handle payment data securely. 1. Generate a Certificate Signing Request (CSR) on your machine using OpenSSL: ```bash # Generate key pair openssl ecparam -genkey -name prime256v1 -out ~/mykey.key -noout # Generate CSR from key pair openssl req -new -sha256 -key ~/mykey.key -out ~/request.csr -subj /CN=www.mydomain.com ``` 2. Go to **Certificates, Identifiers & Profiles** in the Apple Developer Portal 3. Select **Merchant IDs** and click on your Merchant ID 4. Under **Apple Pay Payment Processing Certificate**, click **Create Certificate** 5. In the **Create a New Certificate** page, select **Choose File** under "Upload a Certificate Signing Request" and upload your `~/request.csr` 6. Download the Apple Pay Payment Processing Certificate (`apple_pay.cer`) This certificate can also be found and downloaded later under the Apple Pay Payment Processing Certificate section in your Merchant ID. 7. Move the downloaded file to your working directory (`~/`) and convert it to PEM: ```bash openssl x509 -inform DER -in ~/apple_pay.cer -out ~/apple_pay.pem ``` ## 4. Create Merchant Identity Certificate This certificate allows your server to authenticate itself to Apple's servers during payment processing. 1. Generate a CSR and key file using OpenSSL: ```bash # Generate CSR and key files openssl req -out ~/uploadMe.csr -new -newkey rsa:2048 -nodes -keyout ~/clientCertificate.key ``` In the prompt, enter your details. The **Common Name** should match the one used in the previous step. When asked for a password, leave it blank and press Enter. 2. Go to **Certificates, Identifiers & Profiles** in the Apple Developer Portal 3. Select **Merchant IDs** and click on your Merchant ID (the same one as the previous step) 4. Under **Apple Pay Merchant Identity Certificate**, click **Create Certificate** 5. In the **Create a New Certificate** page, select **Choose File** under "Upload a Certificate Signing Request" and upload your `~/uploadMe.csr` 6. Download the Apple Pay Merchant Identity Certificate (`merchant_id.cer`) This certificate can also be found and downloaded later under the Apple Pay Merchant Identity Certificate section in your Merchant ID. 7. Move the downloaded file to your working directory (`~/`) and convert it to PEM: ```bash openssl x509 -inform der -in ~/merchant_id.cer -out ~/clientCertificate.pem ``` ## 5. Create eWallet Account After completing the previous steps, you should have the following files in your working directory: | File | Generated In | |------|-------------| | `mykey.key` | Step 3 - Payment Processing key pair | | `request.csr` | Step 3 - Payment Processing CSR | | `apple_pay.cer` | Step 3 - Downloaded from Apple | | `apple_pay.pem` | Step 3 - Converted certificate | | `uploadMe.csr` | Step 4 - Merchant Identity CSR | | `clientCertificate.key` | Step 4 - Merchant Identity key | | `merchant_id.cer` | Step 4 - Downloaded from Apple | | `clientCertificate.pem` | Step 4 - Converted certificate | When [setting up an eWallet Account](https://developers.orchestrasolutions.com/guides/library/store-merchant-account), use the content of these files as follows: | eWallet Account Field | Value | |----------------------|-------| | **Name** | Desired name of the eWallet Account - you will use this in your requests | | **eWallet Type** | ApplePay | | **Merchant Identifier** | The identifier from Step 1 (e.g., `merchant.com.example.yourbusiness`) | | **Merchant Display Name** | Desired display name shown to payers | | **Domain Name** | Domain where the Apple Pay button will be hosted - must match the Common Name (CN) set in the certificates | | **Client Certificate Pem** | Contents of `~/clientCertificate.pem` | | **Client Certificate Private Key Pem** | Contents of `~/clientCertificate.key` | | **Payment Certificate Private Key Pem** | Contents of `~/mykey.key` | | **Payment Certificate Pem** | Contents of `~/apple_pay.pem` | ## Testing Use [Apple Pay Sandbox](https://developer.apple.com/apple-pay/sandbox-testing/) with test cards in Safari on macOS or iOS. ## Next Steps Save your Apple Pay credentials in Orchestra Implement Apple Pay in your integration --- # PayPal Setup URL: https://developers.orchestrasolutions.com/guides/library/paypal-setup --- This page is part of **Merchant Account Setup**. [Back to Library Setup →](https://developers.orchestrasolutions.com/guides/library/setup) **Requires:** Verified [PayPal Business](https://www.paypal.com/business) account ## 1. Access Developer Dashboard 1. Go to [PayPal Developer Dashboard](https://developer.paypal.com/dashboard/) 2. Sign in with your PayPal Business account ## 2. Create an App 1. Navigate to **Apps & Credentials** 2. Select **Live** (or **Sandbox** for testing) 3. Click **Create App** 4. Enter a name and select **Merchant** as the app type 5. Click **Create App** ## 3. Copy Credentials - **Client ID** - visible under the app name - **Secret** - click **Show** to reveal ## 4. Store in Orchestra [Store these credentials](https://developers.orchestrasolutions.com/guides/library/store-merchant-account) in the Orchestra Portal for use with the Payments Library. ## Testing Use **Sandbox** credentials and [PayPal sandbox accounts](https://developer.paypal.com/tools/sandbox/) to test without real money. ## Next Steps Save your PayPal credentials in Orchestra Implement PayPal in your integration --- # Bank Pay Setup URL: https://developers.orchestrasolutions.com/guides/library/bankpay-setup --- This page is part of **Merchant Account Setup**. [Back to Library Setup →](https://developers.orchestrasolutions.com/guides/library/setup) Bank Pay collects payment credentials from customers. You'll also need a [payment provider configured](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) in Orchestra to process the transactions. Bank Pay enables customers to pay directly from their bank account. ## Setup Process Bank Pay setup requires coordination with our team to configure your account properly. Email **support@orchestrasolutions.com** to set up Bank Pay for your account. Our team will guide you through: - Account eligibility and requirements - Provider configuration - Testing and go-live process ## After Setup Once configured, [store your Bank Pay credentials](https://developers.orchestrasolutions.com/guides/library/store-merchant-account) in the Orchestra Portal as an eWallet Account. ## Next Steps Save your Bank Pay credentials in Orchestra Implement Bank Pay in your integration --- # UPI Setup URL: https://developers.orchestrasolutions.com/guides/library/upi-setup --- This page is part of **Merchant Account Setup**. [Back to Library Setup →](https://developers.orchestrasolutions.com/guides/library/setup) UPI collects payment credentials from customers. You'll also need a [payment provider configured](https://developers.orchestrasolutions.com/getting-started/add-payment-provider) in Orchestra to process the transactions. UPI (Unified Payments Interface) enables instant bank-to-bank payments, primarily used in India. ## Setup Process UPI setup requires coordination with our team to configure your account properly. Email **support@orchestrasolutions.com** to set up UPI for your account. Our team will guide you through: - Account eligibility and regional requirements - Provider configuration - Testing and go-live process ## After Setup Once configured, [store your UPI credentials](https://developers.orchestrasolutions.com/guides/library/store-merchant-account) in the Orchestra Portal as an eWallet Account. ## Next Steps Save your UPI credentials in Orchestra Implement UPI in your integration --- # Payment Service Provider (PSP) Setup URL: https://developers.orchestrasolutions.com/guides/library/psp-setup --- This page is part of **Merchant Account Setup**. [Back to Library Setup →](https://developers.orchestrasolutions.com/guides/library/setup) A PSP (Payment Service Provider) processes card payments. You need PSP credentials to charge cards, Apple Pay, or Google Pay through Orchestra. Skip this if you only plan to tokenize payment methods or use PayPal/bank transfers. ## 1. Choose a PSP Select from [{supportedIntegrations} supported processors](https://orchestrasolutions.com/integrations/). ## 2. Create a Merchant Account Contact your chosen PSP and complete their onboarding process. Request API access. ## 3. Get API Credentials Each PSP provides different credentials (API keys, secrets, merchant IDs). Refer to your PSP's documentation. ## 4. Create a Payment Gateway Account in Orchestra In the Orchestra Portal, [create a Payment Gateway Account](https://portal.orchestrasolutions.com/#/resource/paymentGateway/create) to store your PSP credentials: 1. Navigate to **Payment Gateway Accounts** and click **Add** 2. Enter a **Name**, a friendly identifier you'll use in API calls (3-64 alphanumeric characters, no spaces) 3. Select the **Payment Gateway Name** from the dropdown (e.g., Credorax, Stripe, Adyen) 4. Enter the **credentials** specific to your PSP (the required fields will appear based on your selection) 5. Optionally assign the account to a specific user, or leave it to auto-assign to your user 6. Click **Save** You can create multiple Payment Gateway Accounts for different PSPs or environments (sandbox/production). ## Next Steps Complete your Payments Library integration Implement card payments --- # Store eWallet Account URL: https://developers.orchestrasolutions.com/guides/library/store-merchant-account --- This page is part of **Merchant Account Setup**. [Back to Library Setup →](https://developers.orchestrasolutions.com/guides/library/setup) Store your digital wallet credentials in Orchestra for use with the Payments Library. eWallet Accounts are used for: - [Apple Pay](https://developers.orchestrasolutions.com/guides/library/applepay-setup) - [Google Pay](https://developers.orchestrasolutions.com/guides/library/googlepay-setup) - [PayPal](https://developers.orchestrasolutions.com/guides/library/paypal-setup) - [Bank Pay](https://developers.orchestrasolutions.com/guides/library/bankpay-setup) - [UPI](https://developers.orchestrasolutions.com/guides/library/upi-setup) Go to the [Orchestra Portal](https://portal.orchestrasolutions.com/#/login). Go to **Resources** > **[eWallet Accounts](https://portal.orchestrasolutions.com/#/resource/eWalletAccount)**. Click **[Add Account](https://portal.orchestrasolutions.com/#/resource/eWalletAccount/create)**. 1. Enter a unique **Name** for this account 2. Select the **eWallet Type** from the dropdown (e.g., GooglePay, ApplePay, PayPal) 3. Enter the required fields for that wallet (e.g., **Merchant Identifier** and **Merchant Display Name** for Google Pay) 4. Click **Save** Repeat for each payment method you want to support. ## Next Steps Complete your Payments Library integration Learn about each payment method --- # Contact Us URL: https://developers.orchestrasolutions.com/support --- Need help? Here's how to reach us. ## Developer Support Forum For technical questions, implementation help, and community discussion: Our support forum on GitHub. Ask questions, share solutions, connect with other developers. ## Email Support For account issues, billing questions, or private matters: **support@orchestrasolutions.com** Response time: Within 1 business day. ## Documentation Feedback Found an error in the docs? Have a suggestion? - Open an issue on [GitHub](https://github.com/orchestra-solutions/p18n/issues) - Or email us at support@orchestrasolutions.com ## Before Reaching Out Check these resources first: Step-by-step first integration guide Full endpoint documentation JavaScript library integration guide Conceptual overview Payment terminology definitions ## Reporting Security Issues If you discover a security vulnerability, **do not** post it publicly. Email us directly at **support@orchestrasolutions.com** with "SECURITY" in the subject line. We take security seriously and will respond promptly. --- # Changelog URL: https://developers.orchestrasolutions.com/changelog --- ## February 16, 2026 ### New: Gateway failover with `fallbackUpgs` `POST /PaymentGateway/charge` now accepts an optional `fallbackUpgs` array. If the primary gateway rejects the charge, Orchestra retries automatically through each gateway in the list in order, stopping at the first success. ```json { "paymentGatewayAccountName": "primary-gateway", "fallbackUpgs": [ { "paymentGatewayAccountName": "backup-gateway-1" }, { "paymentGatewayAccountName": "backup-gateway-2" } ], "amount": 49.99, "currency": "USD", "card": "cardToken" } ``` No changes required if you don't use failover. See the [multi-gateway failover guide](https://developers.orchestrasolutions.com/guides/rest-api/multi-gateway-failover) for details. --- ## February 4, 2026 ### New: eWallet Accounts can now be edited eWallet Accounts (PayPal, BankPay, UPI, and CardPay credentials) can now be updated through the portal. Previously, the only way to change an account's settings was to delete it and re-create it. --- ## January 23, 2026 ### New: Client Certificate support in eWallet sessions `POST /EWalletOperations` now accepts an optional `clientCertificate` parameter. This allows Orchestra to authenticate with your payment gateway using a client certificate during the charge flow. The parameter is supported at the root level and inside each entry of the `fallbackUpgs` array: ```json { "operation": "CHARGE", "paymentGatewayAccountId": "my-gateway", "clientCertificate": "base64-encoded-cert", "fallbackUpgs": [ { "paymentGatewayAccountId": "backup-gateway", "clientCertificate": "base64-encoded-cert-2" } ] } ``` ### New: Mock Credential Provider A mock credential service is now available for testing environments. It returns card-like payment tokens without requiring real payment gateway credentials, making it easier to test the full integration flow before going live. See the [mock PSPs guide](https://developers.orchestrasolutions.com/guides/utilities/mock-psps) for setup instructions. ### New: Mock gateways support 3DS flow The built-in mock payment gateways now support the full 3-D Secure authentication flow. You can use them to test the CardPay 3DS scenario end-to-end in dev and QA environments without a live gateway connection. ### Fix: 400 error response schema corrected The `400 Bad Request` response was incorrectly documented in the API spec as a single `ValidationErrorMessage` object. It now correctly reflects the actual response: an array of `ValidationErrorMessage` objects. No runtime behavior changed - this was a documentation-only correction. ### Update: Developer portal URLs migrated to orchestrasolutions.com Account activation and registration emails now link to `orchestrasolutions.com`. The previous `epaytools.com` domain is no longer used. --- # API Reference URL: https://developers.orchestrasolutions.com/api-reference/overview --- This reference documents all Orchestra API endpoints. Not sure which integration approach is right for you? See [REST API vs Payments Library](https://developers.orchestrasolutions.com/concepts/api-vs-library). ## Base URL All API requests use the same base URL for both production and sandbox: ``` https://api.orchestrasolutions.com ``` All request and response bodies are JSON format. ## Authentication Authenticate all API requests with your API key (created through the [Orchestra Portal](https://portal.orchestrasolutions.com/)). Include it in the `X-Api-Key` header: ```bash curl -X GET "https://api.orchestrasolutions.com/PaymentGateway" \ -H "X-Api-Key: YOUR_API_KEY" ``` --- ## Choose Your Path Direct HTTP calls for charges, refunds, tokenization. You handle card collection and UI. Backend endpoints for the JavaScript library. The library handles card entry UI. --- ## REST API Endpoints Use these endpoints when integrating via direct HTTP calls from your backend. Charge, authorize, capture, refund, and void transactions. Tokenize and retrieve sensitive strings (card numbers, etc). Store and manage your payment provider credentials. Validate API key, list supported gateways. --- ## Payments Library Endpoints Use these endpoints when integrating via the [JavaScript Payments Library](https://developers.orchestrasolutions.com/guides/library/setup). Your server calls these endpoints; the client-side library handles UI. Create a payment session for the client-side library. Verify payment results returned from the library. Store and manage your payment provider credentials. Configure accounts for Apple Pay, Google Pay, PayPal, and more. --- ## Response Codes Orchestra API endpoints use two response patterns: | Pattern | Status Code | Used By | Meaning | |---------|-------------|---------|---------| | **Async** | `202 Accepted` | Payment operations (charge, authorize, capture, refund, void) | Request forwarded to payment gateway. Check response body for gateway result. | | **Sync** | `201 Created` | StringTokens (create) | Operation completed. Resource created in Orchestra. | | **Sync** | `200 OK` | GET operations, status checks | Operation completed successfully. | ### Common Error Codes | Code | Description | |------|-------------| | `400` | Bad request - invalid parameters | | `401` | Not authenticated - invalid or missing API key | | `404` | Resource not found | | `409` | Conflict - rejected by payment gateway or validation failed | | `500` | Internal server error | | `503` | Temporary failure - retry with exponential backoff | Payment operations return `202` because they're forwarded to external gateways asynchronously. The response body contains the gateway's result. StringTokens returns `201` because tokens are stored synchronously in Orchestra's vault. --- ## OpenAPI Specification The Orchestra API is fully described in an OpenAPI 3.0 specification file. You can use this to: - **Import into Postman** or other API clients for quick testing and exploration - **Generate client libraries** in your preferred language using tools like OpenAPI Generator - **Enable IDE autocomplete** for API requests in supported editors - **Build integrations** with API management platforms OAS 3.0 format. Use with Postman, client generators, or your IDE --- # Overview URL: https://developers.orchestrasolutions.com/api-reference/paymentgateway/overview --- [← Back to API Reference](https://developers.orchestrasolutions.com/api-reference/overview) Submit card processing requests to a single API endpoint. Orchestra routes them to your chosen payment gateway, supporting [{supportedIntegrations} processors](https://orchestrasolutions.com/integrations/). Need one we don't support? [Request an integration](https://orchestrasolutions.com/integration-request/) at no cost. ## Key Features - **Single integration**: Connect to any supported processor without separate integrations - **Orchestration workflows**: Build routing logic, retries, and failover - **Multi-tenant support**: Store merchant credentials via [Payment Gateway Accounts](https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/overview) to process on behalf of customers - **Flexible card input**: Send card details inline or reference a [StringToken](https://developers.orchestrasolutions.com/api-reference/stringtokens/overview) For gateway-specific parameters, see [Gateway Requirements](https://developers.orchestrasolutions.com/guides/rest-api/gateway-requirements). --- ## Endpoints Retrieve all supported payment gateways Process a payment charge Authorize a payment for later capture Capture a previously authorized payment Void a transaction Refund a completed transaction Tokenize a card for future use Check transaction status --- # get /PaymentGateway URL: https://developers.orchestrasolutions.com/api-reference/paymentgateway/list-all-payment-gateways --- Complete guide with credential discovery and usage examples --- # post /PaymentGateway/charge URL: https://developers.orchestrasolutions.com/api-reference/paymentgateway/perform-a-payment-gateway-charge-operation --- This method allows you to perform a "charge" operation through your payment gateway. A "charge" operation will request immediate payment from the card and the card owner will see this listed as a transaction in their card statement. If needed, you can void this "charge" operation by using the `DELETE /PaymentGateway/void` method. **Additional parameters may be required** Some payment processors require custom parameters and properties to be added to the request. See [Gateway-Specific Requirements](https://developers.orchestrasolutions.com/guides/rest-api/gateway-requirements) for processors that require additional information. **Payment gateway merchant account credentials** Orchestra offers two options for providing merchant account credentials: 1. **Inline credentials**: Provide the merchant account credentials in the request using the `paymentGatewayAccount` object. 2. **Stored credentials**: Use our [Payment Gateway Accounts](https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/add-or-replace-a-payment-gateway-account) system to pre-upload and store credentials, then reference them with the `paymentGatewayAccountName` parameter. Complete guide with examples, parameters, and best practices --- # post /PaymentGateway/authorize URL: https://developers.orchestrasolutions.com/api-reference/paymentgateway/perform-a-payment-gateway-authorize-operation --- This method allows you to perform an "authorize" operation (also called "preauthorization" or "authorization") through your payment gateway. When you perform the "authorize" operation, the bank that issued the credit card will place an authorization of the total amount of the funds. This is how the bank determines if the funds are available to make the purchase. The card will not actually be "charged" until you perform the "capture" operation (using the `PUT /PaymentGateway/capture` method). **Please note**: Different card brands and different banks allow for different time frames on the lifespan of a payment authorization. Check with your payment processor on how long you have between performing an "authorize" operation and a "capture" operation. If needed, you can void this "authorize" operation using the `DELETE /PaymentGateway/void` method. **Additional parameters may be required** Some payment processors require custom parameters and properties to be added to the request. See [Gateway-Specific Requirements](https://developers.orchestrasolutions.com/guides/rest-api/gateway-requirements) for processors that require additional information. **Payment gateway merchant account credentials** Orchestra offers two options for providing merchant account credentials: 1. **Inline credentials**: Provide the merchant account credentials in the request using the `paymentGatewayAccount` object. 2. **Stored credentials**: Use our [Payment Gateway Accounts](https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/add-or-replace-a-payment-gateway-account) system to pre-upload and store credentials, then reference them with the `paymentGatewayAccountName` parameter. Complete guide with examples, capture flow, and best practices --- # put /PaymentGateway/capture URL: https://developers.orchestrasolutions.com/api-reference/paymentgateway/perform-a-payment-gateway-capture-operation --- **Additional parameters may be required** Some payment processors require custom parameters and properties to be added to the request. See [Gateway-Specific Requirements](https://developers.orchestrasolutions.com/guides/rest-api/gateway-requirements) for processors that require additional information. **Payment gateway merchant account credentials** Orchestra offers two options for providing merchant account credentials: 1. **Inline credentials**: Provide the merchant account credentials in the request using the `paymentGatewayAccount` object. 2. **Stored credentials**: Use our [Payment Gateway Accounts](https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/add-or-replace-a-payment-gateway-account) system to pre-upload and store credentials, then reference them with the `paymentGatewayAccountName` parameter. Complete guide with authorization, capture, and void flows --- # post /PaymentGateway/tokenize URL: https://developers.orchestrasolutions.com/api-reference/paymentgateway/perform-a-payment-gateway-tokenize-operation --- Not all payment gateways support tokenization. Gateway tokens are specific to the payment processor and are used for recurring payments. For general-purpose tokenization, see [String Tokens](https://developers.orchestrasolutions.com/api-reference/stringtokens/overview). Complete guide with examples and comparison to String Tokens --- # put /PaymentGateway/refund URL: https://developers.orchestrasolutions.com/api-reference/paymentgateway/perform-a-payment-gateway-refund-operation --- Complete guide with partial refunds, examples, and best practices --- # delete /PaymentGateway/void URL: https://developers.orchestrasolutions.com/api-reference/paymentgateway/perform-a-payment-gateway-void-operation --- **Additional parameters may be required** Some payment processors require custom parameters and properties to be added to the request. See [Gateway-Specific Requirements](https://developers.orchestrasolutions.com/guides/rest-api/gateway-requirements) for processors that require additional information. **Payment gateway merchant account credentials** Orchestra offers two options for providing merchant account credentials: 1. **Inline credentials**: Provide the merchant account credentials in the request using the `paymentGatewayAccount` object. 2. **Stored credentials**: Use our [Payment Gateway Accounts](https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/add-or-replace-a-payment-gateway-account) system to pre-upload and store credentials, then reference them with the `paymentGatewayAccountName` parameter. Complete guide with examples and when to use void vs refund --- # post /PaymentGateway/status URL: https://developers.orchestrasolutions.com/api-reference/paymentgateway/perform-a-payment-gateway-status-operation --- Complete guide with timeout handling and reconciliation examples --- # Overview URL: https://developers.orchestrasolutions.com/api-reference/stringtokens/overview --- [← Back to API Reference](https://developers.orchestrasolutions.com/api-reference/overview) String Tokens provide a secure way to tokenize sensitive data. Instead of storing sensitive information in your own systems, you send it to Orchestra and receive a token in return. The token can later be used to retrieve the original data or reference it in other Orchestra API calls. ## What Can You Tokenize? You can tokenize any string up to 16,384 characters, including: - **Card PANs** - Store card numbers securely and reference them in payment requests - **CVVs** - Tokenize CVV codes separately for enhanced security - **Personal identifiers** - Social security numbers, national IDs, passport numbers - **Addresses** - Billing or shipping addresses containing PII - **JSON objects** - Store structured data as a JSON string - **Any sensitive string** - Anything you want to keep out of your systems **Security Best Practice**: Store each piece of sensitive data in its own individual token rather than combining multiple values. For example, create separate tokens for the card PAN and CVV. This limits exposure if a token is compromised. ## Why Use String Tokens? - **Reduce PCI scope** - Keep card data out of your systems by storing it in Orchestra's PCI-compliant vault - **Simplify compliance** - Avoid storing sensitive PII directly in your databases - **Flexible storage** - Tokens persist until you delete them, with no expiration - **Easy integration** - Use tokens in payment requests by prefixing with `@` (e.g., `@your-token-id`) **Compliance note**: Retrieving tokenized card data exposes your system to raw card details, putting you in scope for PCI compliance. Consider using tokens only for storage and referencing them in payment requests without retrieval. --- ## Endpoints Tokenize any string and receive a token reference. Get the original string from a token. Get token metadata (creation time, etc.) without exposing the content. Permanently remove a token and its stored data. Deleting a token is permanent and cannot be undone. Ensure no active integrations reference the token before deleting. --- # post /StringTokens URL: https://developers.orchestrasolutions.com/api-reference/stringtokens/store-and-tokenize-a-string --- Complete guide with examples, PCI compliance, and using tokens in payments --- # get /StringTokens/{token} URL: https://developers.orchestrasolutions.com/api-reference/stringtokens/retrieve-content-of-stringtoken --- **In scope of compliance** If you choose to use the StringToken to store card details (whether the card number (PAN), the CVV, or the full card details), when retrieving the data stored behind a token, your system is then exposed to the raw card details and as such is in scope of PCI compliance. The same applies to any other type of sensitive data. By retrieving the data, your system is then in scope of the relevant compliance. If you are unsure whether you should use this method, please reach out to our team and we would be happy to review your use case and explain your options. Complete guide with examples and PCI compliance considerations --- # delete /StringTokens/{token} URL: https://developers.orchestrasolutions.com/api-reference/stringtokens/delete-an-existing-string-by-token --- **Deleting a token cannot be undone** You can delete a string token at any time. However, this operation cannot be undone. Once a stringToken has been deleted, it cannot be retrieved or returned. Complete guide with examples and token lifecycle --- # get /StringTokens/{token}/meta URL: https://developers.orchestrasolutions.com/api-reference/stringtokens/retrieve-meta-data-of-a-stringtoken --- Complete guide with token metadata and lifecycle management --- # Overview URL: https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/overview --- [← Back to API Reference](https://developers.orchestrasolutions.com/api-reference/overview) Payment Gateway Accounts store your PSP (Payment Service Provider) credentials securely in Orchestra. Once stored, you can reference them by name when processing payments through either the [REST API](https://developers.orchestrasolutions.com/api-reference/paymentgateway/overview) or the [Payments Library](https://developers.orchestrasolutions.com/guides/library/setup). ## How It Works 1. **Choose a PSP** from Orchestra's [{supportedIntegrations} supported processors](https://orchestrasolutions.com/integrations/) 2. **Obtain credentials** from your PSP (API keys, merchant IDs, etc.) 3. **Store in Orchestra** via the Portal or this API 4. **Reference by name** in your payment requests ## Why Use Payment Gateway Accounts? - **Security** - Keep sensitive PSP credentials out of your own systems - **Multi-gateway setups** - Store credentials for multiple processors and switch between them dynamically - **Failover support** - Configure multiple PSPs and let Orchestra route transactions automatically - **Platforms/SaaS** - Process payments on behalf of your customers using their merchant accounts - **Environment separation** - Maintain separate accounts for sandbox and production You can also provide PSP credentials inline with each request instead of storing them, but stored accounts are recommended for security and convenience. **Prefer a UI?** You can also manage Payment Gateway Accounts through the [Orchestra Portal](https://portal.orchestrasolutions.com/#/resource/paymentGateway/create). The API is useful for automation, CI/CD pipelines, or programmatic management. ## Finding Required Credentials Each PSP requires different credentials. Use the [List Gateways](https://developers.orchestrasolutions.com/api-reference/paymentgateway/list-all-payment-gateways) endpoint to find the `credentialsNames` required for your PSP, or check the [Gateway Requirements](https://developers.orchestrasolutions.com/guides/rest-api/gateway-requirements) guide for PSP-specific details. --- ## Endpoints Retrieve all stored payment gateway accounts. Get details for a specific account including credentials. Store new PSP credentials or update existing ones. Permanently remove a stored account. Deleting an account is permanent. Ensure no active integrations reference the account before deleting. --- # get /PaymentGatewayAccounts URL: https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/list-payment-gateway-accounts --- ## related Complete guide with account management and naming conventions --- # get /PaymentGatewayAccounts/{name} URL: https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/retrieve-payment-gateway-account --- ## related Complete guide with account management and best practices --- # put /PaymentGatewayAccounts/{name} URL: https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/add-or-replace-a-payment-gateway-account --- ## related Complete guide with credential structure and naming conventions --- # delete /PaymentGatewayAccounts/{name} URL: https://developers.orchestrasolutions.com/api-reference/paymentgatewayaccounts/delete-a-payment-gateway-account --- ## related Complete guide with account lifecycle management --- # Card Tools URL: https://developers.orchestrasolutions.com/api-reference/tools/overview --- The Card Tools endpoints let you retrieve card metadata, identify card brands, validate card numbers, and assess transaction risk - all from the card's BIN/IIN (the first 6 to 11 digits). ## Endpoints Identify the card brand and get the brand logo URL Get full card metadata: brand, type, category, issuer, country Validate a card number using the Luhn algorithm Risk assessment using card BIN + payer billing/IP data ## Common Use Cases - **BIN-based routing** - Use the metadata lookup to get the issuer country and route payments to the optimal PSP per region - **Card form UX** - Use the brand lookup to display the card brand logo in real time as the user types - **Fraud screening** - Use card validation to compare the card's issuer country against the payer's IP and billing address - **Input validation** - Use the Luhn check to validate card numbers before submitting a payment The data returned by these endpoints is non-sensitive and does not put the caller in PCI scope. --- # get /Tools/brand URL: https://developers.orchestrasolutions.com/api-reference/tools/brand-lookup --- --- # get /Tools/iin URL: https://developers.orchestrasolutions.com/api-reference/tools/metadata-lookup --- --- # get /Tools/luhn URL: https://developers.orchestrasolutions.com/api-reference/tools/luhn-validation --- --- # post /Tools/validate URL: https://developers.orchestrasolutions.com/api-reference/tools/card-validation --- --- # get /Utils/apiKey URL: https://developers.orchestrasolutions.com/api-reference/utils/validate-apikey --- ## related Complete guide with health check and environment verification examples --- # Overview URL: https://developers.orchestrasolutions.com/api-reference/ewalletoperations/overview --- [← Back to API Reference](https://developers.orchestrasolutions.com/api-reference/overview) These endpoints power the [Payments Library](https://developers.orchestrasolutions.com/guides/library/setup), a JavaScript library that renders payment buttons for cards, Apple Pay, Google Pay, PayPal, Bank Pay, and UPI. Your server calls these endpoints; the client-side library handles the payment UI. ## How It Works 1. **Your server** calls [Start Session](https://developers.orchestrasolutions.com/api-reference/ewalletoperations/start-an-ewallet-session) to create a payment session 2. **Your server** passes the session JWT to the client, which uses it to initialize the library. The library then displays payment options and collects payment details from the customer 3. **The library** returns the transaction result to the client, which passes it to your server 4. **Your server** calls [Validate Results](https://developers.orchestrasolutions.com/api-reference/ewalletoperations/validate-operation-results) to verify the payment completed successfully These are server-side endpoints. For client-side integration, see the [Library Setup Guide](https://developers.orchestrasolutions.com/guides/library/setup). --- ## Endpoints Create a payment session for the client-side library. Verify payment results returned from the library. --- # post /EWalletOperations URL: https://developers.orchestrasolutions.com/api-reference/ewalletoperations/start-an-ewallet-session --- ## Prerequisites Configure credentials for Apple Pay, Google Pay, PayPal, etc. Configure your Payment Gateway Account for processing. ## Related Complete guide with session configuration and payment button setup --- # post /EWalletOperations/validateResults URL: https://developers.orchestrasolutions.com/api-reference/ewalletoperations/validate-operation-results --- ## related Result parsing, data structures, and validation