Files
2026-09-09 13:55:33 +08:00

73 lines
2.7 KiB
JavaScript

/***********************************************************************************************************************************************************************
* File Name: paypal.provider.js
* Type of Program: Payment Provider
* Description: PayPal Orders API — create order, capture order, refund capture.
* Canonical provider used by payment.service.js via the provider registry.
* Author: Kenneth Obsequio (@lash0000)
* Date Created: Jun. 29, 2026
***********************************************************************************************************************************************************************/
'use strict';
const axios = require('axios');
const BASE_URL = process.env.PAYPAL_ENV === 'live'
? 'https://api-m.paypal.com'
: 'https://api-m.sandbox.paypal.com';
const getAccessToken = async () => {
const { data } = await axios.post(
`${BASE_URL}/v1/oauth2/token`,
'grant_type=client_credentials',
{
auth: {
username: process.env.PAYPAL_CLIENT_ID,
password: process.env.PAYPAL_CLIENT_SECRET,
},
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
}
);
return data.access_token;
};
exports.createOrder = async ({ amount, currency = 'USD', referenceId, returnUrl, cancelUrl }) => {
const token = await getAccessToken();
const { data } = await axios.post(
`${BASE_URL}/v2/checkout/orders`,
{
intent: 'CAPTURE',
purchase_units: [{
reference_id: referenceId,
amount: { currency_code: currency, value: String(amount) },
}],
application_context: {
return_url: returnUrl ?? `${process.env.FRONTEND_URL}/subscriptions/checkout`,
cancel_url: cancelUrl ?? `${process.env.FRONTEND_URL}/subscriptions/checkout?cancelled=true`,
brand_name: process.env.PAYPAL_BRAND_NAME ?? 'STARR',
user_action: 'PAY_NOW',
},
},
{ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' } }
);
return data;
};
exports.captureOrder = async (orderId) => {
const token = await getAccessToken();
const { data } = await axios.post(
`${BASE_URL}/v2/checkout/orders/${orderId}/capture`,
{},
{ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' } }
);
return data;
};
exports.refundCapture = async (captureId, amount, currency = 'USD') => {
const token = await getAccessToken();
const { data } = await axios.post(
`${BASE_URL}/v2/payments/captures/${captureId}/refund`,
{ amount: { value: String(amount), currency_code: currency } },
{ headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' } }
);
return data;
};