Payment Gateway Integration: Add Payments to Your App in 10 Minutes
A payment gateway integration connects your website or app to a service that takes the payment and tells your backend when it's done. The simplest integration uses a hosted checkout: your server creates a payment, the customer pays on the gateway's page, and a signed webhook marks the order paid.
This guide walks through that flow with the OrcaRail API and SDKs, for a web app and a mobile app, in a sandbox with no real funds. Customers pay in crypto, and you receive the stablecoin you choose, such as USDC or USDT.
How a hosted payment gateway integration works
| Step | Who | What happens |
|---|---|---|
| 1. Create | Your backend | Creates a payment intent with the amount, the token and network you receive, and return/cancel URLs |
| 2. Redirect | Your app | Sends the customer to the hosted pay page |
| 3. Pay | Customer | Pays on pay.orcarail.com with their wallet |
| 4. Return | Your backend | Completes the intent when the customer lands on your return URL |
| 5. Webhook | OrcaRail → your backend | Sends a signed payment_intent.completed event; you fulfill the order |
Your servers never handle wallets, private keys or chain monitoring. The browser redirect alone never marks an order paid: your backend checks with the API and trusts only signed webhooks.
Before you start
- Sign up at app.orcarail.com and finish the guided setup.
- Click Go to sandbox and create an API key (
ak_test_…). Copy the key, the secret and the webhook signing secret. The secret is shown once. See Create a sandbox. - Set the API key's webhook URL, for example
https://yourapp.com/webhooks/orcarail. - Pick the token and network you receive. IDs come from
GET /payments/networksandGET /payments/networks/:id/tokens. See Networks and tokens.
Integrate with the Node.js SDK
Install the Node.js SDK:
npm install @orcarail/node
1. Create a payment and redirect
import OrcaRail from '@orcarail/node'
const orcarail = new OrcaRail(
process.env.ORCARAIL_API_KEY!, // ak_test_… in the sandbox
process.env.ORCARAIL_API_SECRET!
)
const intent = await orcarail.paymentIntents.create({
amount: '100.00',
currency: 'usd',
payment_method_types: ['crypto'],
tokenId: '<token-id>', // e.g. USDC
networkId: '<network-id>', // e.g. Base
return_url: 'https://yourapp.com/success',
cancel_url: 'https://yourapp.com/cancel',
description: 'Order #12345',
metadata: { order_id: '12345' },
})
const confirmed = await orcarail.paymentIntents.confirm(intent.id, {
client_secret: intent.client_secret!,
return_url: 'https://yourapp.com/success',
})
// Redirect the customer to confirmed.pay_url
2. Complete the payment on return
When the customer lands on your return URL, complete the intent from your backend. This finalizes the payment and makes it withdrawable. If it is not confirmed on-chain yet, the intent stays processing; call complete again later.
const completed = await orcarail.paymentIntents.complete(intent.id)
3. Verify the webhook
Use the raw request body and the x-webhook-signature header:
app.post(
'/webhooks/orcarail',
express.raw({ type: 'application/json' }),
(req, res) => {
try {
const event = orcarail.webhooks.constructEvent(
req.body,
req.headers['x-webhook-signature'],
process.env.ORCARAIL_WEBHOOK_SECRET
)
if (event.type === 'payment_intent.completed') {
// mark the order paid (idempotently)
}
res.status(200).json({ received: true })
} catch (err) {
res.status(400).send('Invalid signature')
}
}
)
Events carry livemode. Never fulfill real orders from livemode: false events. See Webhook signatures and Webhook events.
Integrate with PHP or Laravel
The same flow works with the PHP SDK, and the Laravel Cashier package adds crypto subscriptions to Laravel apps. Not using an SDK? Call the REST API directly: see the API reference.
Payment gateway for a mobile app
A mobile app should never hold your API secret. Keep the integration on your backend:
- The app asks your backend to create the payment.
- The backend creates and confirms the intent and returns
pay_url. - The app opens
pay_urlin an in-app browser or the system browser. - The customer returns to your
return_url, and your backend completes the intent. - Your backend receives the webhook and updates the app, for example with a push message or on the next refresh.
Test the integration in the sandbox
- Sandbox keys (
ak_test_) use testnets only.orcarail.livemodeisfalse. - Call
await orcarail.paymentIntents.simulate(id)or click Simulate payment on the sandbox pay page to finish a payment without a wallet. See Simulate payments. - When everything works, create live keys in your live organization and switch the token and network to mainnet. See Going live.
Let an AI coding agent do the integration
The OrcaRail MCP server lets Claude Code, Cursor or Codex create payment intents, products and subscriptions for you, and the docs are available as plain text for LLMs. See Building with AI.
FAQ
How long does a payment gateway integration take?
With a hosted checkout and an SDK, a basic integration is three backend calls and one webhook route. Most of the time goes into testing in the sandbox.
Do I need my own checkout page?
No. Customers pay on the hosted pay page. If you want no code at all, embed a pricing widget instead; see Payment gateway for website.
How do I know a payment really happened?
Trust only the signed webhook, or check the intent with the API from your backend. Never trust the browser redirect alone.
What does it cost?
Hosted OrcaRail charges 0.5% per completed transaction after the first 100 free transactions. Network fees are separate. See pricing.
Can I accept recurring payments?
Yes, with the subscriptions API. See recurring crypto payments and OrcaRail subscriptions.
