Unified Pay Docs

Getting Started

  • Introduction
  • Getting Started

Payment Providers

  • Stripe
  • PayPal
  • Razorpay

Resources

  • API Reference
  • Best Practices
  • FAQ
DocumentationFAQ

FAQ

Frequently asked questions and troubleshooting

Documentation Team

Frequently Asked Questions (FAQ)

How do I get API credentials?

Obtain credentials from the respective gateway dashboards:

  • Stripe: Stripe Dashboard
  • PayPal: PayPal Developer Console
  • Razorpay : Razorpay Dashboard

Tip: Use test/sandbox credentials during development and never hard-code secrets in your code.

Why is my webhook failing?

Common reasons for webhook failures:

  • Incorrect webhookSecret (Stripe) or webhookId (PayPal)
  • Endpoint not publicly accessible or not responding with status 200
  • Request body or headers not correctly passed to the handleWebhookEvent method
  • For Stripe: Missing or incorrect stripe-signature header
  • For PayPal: Missing PayPal transmission headers for signature verification

Tip: Log incoming webhook payloads in a development environment to debug signature verification issues. Use tools like ngrok for local webhook testing.

Can I use multiple gateways?

Yes. You can register multiple gateways with createGateways:

const { stripe, paypal } = createGateways([
  { gateway: "stripe", config: stripeConfig },
  { gateway: "paypal", config: paypalConfig },
]);

// Call methods on the desired gateway
const stripePayment = await stripe.processPayment(100, "usd");
const paypalPayment = await paypal.processPayment(100, "USD");

Tip: Select a gateway dynamically based on user preference, region, or payment method. Each gateway may have different currency requirements (lowercase for Stripe, uppercase for PayPal).

How do I handle partial refunds?

Call processRefund with the transaction ID and the amount to refund:

// Partial refund
const partialRefund = await stripe.processRefund("pi_xxx", 50);
const paypalPartialRefund = await paypal.processRefund(
  "transaction_id_xxx",
  50
);

// Full refund (omit amount parameter)
const fullRefund = await stripe.processRefund("pi_xxx");
  • Omitting the amount parameter issues a full refund
  • The response includes refundId and amount refunded

How do I test payments locally?

For local development:

  1. Use webhook testing tools: ngrok, localtunnel, or similar to expose your local server

  2. Set up test credentials: Use sandbox/test keys from your gateway dashboard

  3. Test webhook endpoints:

    • Stripe: http://localhost:3000/webhook/stripe
    • PayPal: http://localhost:3000/webhook/paypal
    • Razorpay: http://localhost:3000/webhook/razorpay
  4. Use test payment methods: Each gateway provides test card numbers and PayPal sandbox accounts

    Tip: Always respond with HTTP 200 status to acknowledge webhook receipt, even for unhandled events.

Which Payment Gateways Are Supported?

Currently available gateways:

  • ✅ Stripe: Ready for production use
  • ✅ PayPal: Ready for production use
  • ✅ Razorpay: Ready for production use
  • ⚠️ Square: Work in progress
Previous
Best Practices

Was this helpful?

Help us improve our documentation by providing feedback.