Unified Pay Docs

Getting Started

  • Introduction
  • Getting Started

Payment Providers

  • Stripe
  • PayPal
  • Razorpay

Resources

  • API Reference
  • Best Practices
  • FAQ
DocumentationStripe Integration

Stripe Integration

Complete guide for integrating Stripe payments with unified-pay-core

Documentation Team

This guide explains how to integrate the Stripe payment gateway using the unified-pay-core package. It covers setup, configuration, and key operations like creating payments, capturing payments, processing refunds, and handling webhooks.

Prerequisites

  • Node.js and npm installed.
  • A Stripe account with API keys (test or live).
  • A webhook secret for verifying webhook events.
  • Install the unified-pay-core package:
npm install unified-pay-core

Setup

Obtain Stripe Credentials

  1. Log in to your Stripe Dashboard.
  2. Get your Secret Key (sk_test_... for testing, sk_live_... for production).
  3. Set up a webhook endpoint in Stripe and obtain the Webhook Secret (whsec_...).

Install Dependencies

Ensure you have express and cors for the example server:

npm install express cors

Configure the Gateway

Initialize the Stripe gateway using the createGateways function from unified-pay-core.

const express = require("express");
const cors = require("cors");
const { createGateways } = require("unified-pay-core");

const app = express();
app.use(cors());
app.use("/webhook", express.raw({ type: "application/json" }));
app.use(express.json());

const { stripe } = createGateways([
  {
    gateway: "stripe",
    config: {
      apiSecret: process.env.API_SECRET,
      environment: "sandbox",
      webhookId: process.env.WEBHOOK_SECRET,
    },
  },
]);

Key Operations

1. Create a Payment

Initiate a payment request to create a PaymentIntent.

app.post("/create-payment", async (req, res) => {
  try {
    const { amount = 20 } = req.body;
    const payment = await stripe.processPayment(amount, "usd", {
      test_run: "Sample Payment",
    });
    res.json({
      success: true,
      transactionId: payment.transactionId,
      clientSecret: payment.metadata?.clientSecret || null,
    });
  } catch (err) {
    console.error("Payment creation error:", err);
    res.status(500).json({ success: false, error: "Payment creation failed" });
  }
});

Input:

  • amount: Payment amount (e.g., 20 for $20.00).
  • currency: Currency code (e.g., "usd").
  • metadata: Optional key-value pairs for additional data.

Output:

  • transactionId: Stripe PaymentIntent ID (pi_...).
  • clientSecret: Used for client-side confirmation (e.g., 3D Secure).

2. Capture a Payment

Capture a previously authorized payment (if captureMethod was set to "manual").

app.get("/return", async (req, res) => {
  try {
    const { transactionId } = req.query;
    if (!transactionId) {
      return res.status(400).json({ error: "Missing transactionId" });
    }
    const capture = await stripe.capturePayment(transactionId);
    const verification = await stripe.verifyPayment(capture.transactionId);
    res.json({ capture, verification });
  } catch (err) {
    console.error("Payment capture error:", err);
    res.status(500).json({ error: "Payment capture failed" });
  }
});

Input:

  • transactionId: The PaymentIntent ID to capture.

Output:

  • capture: Payment response with status, amount, and currency.
  • verification: Verification details confirming the payment status.

3. Process a Refund

Refund a payment (full or partial).

app.post("/refund", async (req, res) => {
  try {
    const { transactionId, amount } = req.body;
    if (!transactionId) {
      return res.status(400).json({ error: "transactionId is required" });
    }
    const refund = await stripe.processRefund(
      transactionId,
      amount ? parseFloat(amount) : undefined
    );
    res.json({
      success: refund.success,
      refundId: refund.refundId,
      transactionId,
      status: refund.status,
      amount: refund.amount,
      currency: refund.currency,
    });
  } catch (err) {
    console.error("Refund error:", err);
    res.status(500).json({ success: false, error: "Refund failed" });
  }
});

Input:

  • transactionId: The PaymentIntent ID to refund.
  • amount: Optional partial refund amount (e.g., 10 for $10.00).

Output:

  • refundId: Stripe Refund ID (re_...).
  • status: Refund status (succeeded, pending, failed).

4. Verify a Payment

Verify the status of a payment.

const verification = await stripe.verifyPayment(transactionId);

Input:

  • transactionId: The PaymentIntent ID to verify.

Output:

  • verified: Boolean indicating if the verification was successful.
  • status: Payment status (succeeded, pending, failed, cancelled).
  • isValid: Boolean indicating if the payment is valid (e.g., succeeded).

5. Handle Webhooks

Set up a webhook endpoint to receive and process Stripe events.

app.post("/webhook/stripe", async (req, res) => {
  try {
    const result = await stripe.handleWebhookEvent(req.body, req.headers);
    res.status(result === "INVALID" ? 400 : 200).send(result);
  } catch (error) {
    console.error("Webhook processing error:", error);
    res.status(500).send("Webhook processing failed");
  }
});

Setup:

  • Use express.raw({ type: "application/json" }) for the webhook route to preserve the raw body for signature verification.
  • Configure the webhook URL in the Stripe Dashboard (e.g., https://yourdomain.com/webhook/stripe).

Supported Events:

  • payment_intent.succeeded
  • charge.captured
  • charge.succeeded
  • payment_intent.payment_failed
  • charge.failed
  • charge.refunded
  • refund.created
  • refund.updated

Webhook Testing

  1. Use tools like ngrok to expose your local server: ngrok http 3000.
  2. Update the webhook URL in the Stripe Dashboard.
  3. Test events like payment_intent.succeeded or charge.refunded using Stripe's test tools.

Notes

  • Amount Handling: Stripe expects amounts in cents (e.g., $20.00 = 2000).
  • 3D Secure: Enable require3DS: true in processPayment options for enhanced security.
  • Webhook Secret: Ensure webhookId is set to verify webhook signatures.
  • Error Handling: Check success and error fields in responses to handle failures.
Previous
Getting Started
Next
PayPal Integration

Was this helpful?

Help us improve our documentation by providing feedback.