Skip to main content
Shopify’s Payments Apps API lets you bring your own payment provider to the Shopify checkout. When a customer completes checkout, Shopify sends the payment details to your app’s backend, and your app processes the charge through Accelebit. This guide covers everything you need to build and configure that integration.

Architecture

The sequence below shows how Shopify, your app, and Accelebit interact during a checkout.

Prerequisites

Before you start, make sure you have:
1

Create the Shopify app and configure endpoints

Set up your Shopify app with the Payments App extension. Register the following endpoints in your app configuration:
EndpointPurpose
POST /payments/sessionReceives payment sessions from Shopify
POST /payments/session/resolveCalled by your background worker to resolve sessions
POST /payments/refundHandles refund requests from Shopify
2

Handle payment sessions

When a customer checks out, Shopify sends a payment session to your app. Extract the card and billing details from the session and forward them to Accelebit. Resolve or reject the Shopify session based on the result.
import express from 'express';
import crypto from 'node:crypto';

const app = express();
app.use(express.json());

app.post('/payments/session', async (req, res) => {
  const { id, amount, currency, payment_method, customer } = req.body;

  try {
    // Create payment through Accelebit
    const response = await fetch('https://api.gateway.accelebit.com/v1/payments', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': process.env.ACCELEBIT_SECRET_KEY!,
        'Idempotency-Key': `shopify_${id}`,
      },
      body: JSON.stringify({
        amount: amount.toString(),
        currency: currency.toUpperCase(),
        paymentMethod: 'card',
        customerId: customer.email,
        card: {
          number: payment_method.data.card_number,
          expiryMonth: payment_method.data.expiry_month,
          expiryYear: payment_method.data.expiry_year,
          cvv: payment_method.data.cvv,
          holderName: `${customer.first_name} ${customer.last_name}`,
        },
        billing: {
          firstName: customer.first_name,
          lastName: customer.last_name,
          email: customer.email,
          phone: customer.phone || '+00000000000',
          country: customer.billing_address.country_code,
          address: customer.billing_address.address1,
          addressLine2: customer.billing_address.address2 || undefined,
          city: customer.billing_address.city,
          postalCode: customer.billing_address.zip,
          state: customer.billing_address.province_code || undefined,
        },
        merchantRef: `shopify_order_${id}`,
        returnUrl: `https://yourapp.com/payments/3ds-callback?session=${id}`,
      }),
    });

    const result = await response.json();

    if (result.data?.threeDsRequired) {
      // Redirect customer to 3DS
      return res.json({
        redirect_url: result.data.threeDsData.redirectUrl,
      });
    }

    if (result.data?.status === 'captured') {
      // Payment succeeded - resolve the session
      return res.json({ status: 'resolved' });
    }

    // Payment failed
    return res.json({
      status: 'rejected',
      error: result.error?.message || 'Payment failed',
    });
  } catch (error) {
    return res.status(500).json({
      status: 'rejected',
      error: 'Internal server error',
    });
  }
});
3

Handle 3DS callbacks

When 3DS completes, Accelebit redirects the customer back to your returnUrl. Look up the payment by merchant reference, then resolve or reject the Shopify session accordingly.
app.get('/payments/3ds-callback', async (req, res) => {
  const { session: sessionId } = req.query;

  // Look up the Accelebit payment by merchant reference
  const paymentRes = await fetch(
    `https://api.gateway.accelebit.com/v1/payments?merchantRef=shopify_order_${sessionId}`,
    {
      headers: { 'X-API-Key': process.env.ACCELEBIT_SECRET_KEY! },
    }
  );

  const payment = await paymentRes.json();

  if (payment.data?.status === 'captured') {
    // Resolve the Shopify payment session
    await resolveShopifySession(sessionId, 'resolved');
  } else {
    await resolveShopifySession(sessionId, 'rejected');
  }

  res.redirect(`https://yourshop.myshopify.com/checkouts/complete`);
});
4

Handle refunds

When a merchant issues a refund from the Shopify admin, Shopify sends a refund request to your app. Forward the refund to Accelebit using the stored transaction ID.
app.post('/payments/refund', async (req, res) => {
  const { id, payment_id, amount, currency } = req.body;

  const response = await fetch('https://api.gateway.accelebit.com/v1/refunds', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.ACCELEBIT_SECRET_KEY!,
      'Idempotency-Key': `shopify_refund_${id}`,
    },
    body: JSON.stringify({
      transactionId: payment_id, // Your stored Accelebit transaction ID
      amount: amount.toString(),
      currency: currency.toUpperCase(),
      reason: 'Refund from Shopify admin',
    }),
  });

  const result = await response.json();

  if (response.ok) {
    return res.json({ status: 'resolved' });
  }

  return res.json({
    status: 'rejected',
    error: result.error?.message || 'Refund failed',
  });
});
5

Configure webhooks in the Accelebit Dashboard

Set up an Accelebit webhook endpoint so your app receives real-time payment status updates. This keeps Shopify order statuses accurate even if the customer closes their browser during the 3DS challenge.In the Accelebit Dashboard, add a webhook URL pointing to your app:
https://yourapp.com/webhooks/accelebit
Subscribe to the following events:
  • payment.captured
  • payment.failed
  • refund.created
See Webhooks for signature verification details.

Testing

Before going live, verify your integration end-to-end:
  1. Use your Accelebit test secret key (smtgw_sk_test_...).
  2. Use a Shopify development store.
  3. Use card number 4111111111111111—this processes successfully in test mode.
  4. Issue a refund from the Shopify admin and confirm it processes through Accelebit.