payfyio
Providers

PayPal

PayPal Orders v2 integration with the buyer-approval redirect flow.

PayPal is integrated via the Orders v2 REST API. Authentication is OAuth2 client credentials — apiKey is your client id, secretKey is your client secret. PayPal handles SCA on its own approval page; payfyio returns an HTML redirect to that approval URL through threeDSHtmlContent.

Direct card capture (raw PAN) is not exposed by this provider. PayPal's Advanced Card Processing entitlement varies per merchant. Use the buyer-approval flow described below.

Configuration

paypal: {
  enabled: true,
  config: {
    apiKey: process.env.PAYPAL_CLIENT_ID!,
    secretKey: process.env.PAYPAL_CLIENT_SECRET!,
  },
}

baseUrl defaults to https://api-m.sandbox.paypal.com (sandbox mode) or https://api-m.paypal.com (production mode).

Buyer Approval Flow

// 1) Create the order and redirect the buyer to PayPal.
const init = await payment.paypal.initThreeDSPayment({
  price: '49.99',
  paidPrice: '49.99',
  currency: 'USD',
  basketId: 'order-1',
  callbackUrl: 'https://yoursite.com/paypal/return',
  paymentCard: { /* unused — PayPal collects payment method on its page */ } as any,
  buyer: { id, name, surname, email, ip, /* … */ },
  shippingAddress: { /* … */ },
  billingAddress: { /* … */ },
  basketItems: [{ id, name, category1, itemType: 'PHYSICAL', price: '49.99' }],
});

// init.threeDSHtmlContent → render to redirect the user to PayPal.

// 2) On return, PayPal appends `?token=<orderId>&PayerID=…` to your callbackUrl.
const final = await payment.paypal.completeThreeDSPayment(req.query);
// final.status === 'success' on a captured order

Refund

refund looks up the captured payment id from the order, then issues a partial-or-full refund:

await payment.paypal.refund({ paymentId: orderId, price: '49.99', currency: 'USD', ip: '…' });

Cancel / Get

// Cancel only succeeds for orders that have not yet been captured.
await payment.paypal.cancel({ paymentId: orderId, ip: '…' });
await payment.paypal.getPayment(orderId);

On this page