PayPal Payments
Integrate PayPal for order creation, payment capture, and webhooks.
Configuration
pay({
paypal: {
clientId: process.env.PAYPAL_CLIENT_ID,
clientSecret: process.env.PAYPAL_CLIENT_SECRET,
sandbox: process.env.NODE_ENV !== "production",
currency: "USD",
},
});
Creating Orders
Programmatic
const order = await app.pay.paypal.createOrder({
amount: 29.99,
currency: "USD",
description: "Pro Plan - Monthly",
returnUrl: "https://myapp.com/paypal/success",
cancelUrl: "https://myapp.com/paypal/cancel",
metadata: { userId: "user-123", plan: "pro" },
});
console.log(order.orderId); // PayPal order ID
console.log(order.approvalUrl); // Redirect user here
REST API
curl -X POST http://localhost:3000/pay/paypal/order \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGci..." \
-d '{
"amount": 29.99,
"currency": "USD",
"description": "Pro Plan - Monthly",
"returnUrl": "https://myapp.com/paypal/success",
"cancelUrl": "https://myapp.com/paypal/cancel"
}'
Response (200):
{
"orderId": "5O190127TN364715T",
"approvalUrl": "https://www.paypal.com/checkoutnow?token=5O190127TN364715T",
"status": "CREATED"
}
Capturing Payments
After the user approves the payment on PayPal, capture it:
Programmatic
const result = await app.pay.paypal.captureOrder(orderId);
console.log(result.status); // "COMPLETED"
console.log(result.transactionId); // Internal transaction ID
REST API
curl -X POST http://localhost:3000/pay/paypal/capture/5O190127TN364715T \
-H "Authorization: Bearer eyJhbGci..."
Response (200):
{
"orderId": "5O190127TN364715T",
"status": "COMPLETED",
"transactionId": "65a1b2c3d4e5f6a7b8c9d0e1",
"amount": 29.99,
"currency": "USD"
}
Webhooks
FluxKit handles PayPal webhooks at POST /pay/paypal/webhook. Configure the webhook URL in your PayPal dashboard:
https://myapp.com/pay/paypal/webhook
Listening for Events
app.pay.paypal.on("PAYMENT.CAPTURE.COMPLETED", async (event) => {
const capture = event.resource;
console.log(`Payment captured: $${capture.amount.value}`);
});
app.pay.paypal.on("PAYMENT.CAPTURE.REFUNDED", async (event) => {
// Handle refund
});
Refunds
const refund = await app.pay.paypal.refund(transactionId, {
amount: 10.00, // Partial refund
reason: "Customer request",
});
curl -X POST http://localhost:3000/pay/paypal/refund \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGci..." \
-d '{
"transactionId": "65a1b2c3d4e5f6a7b8c9d0e1",
"amount": 10.00,
"reason": "Customer request"
}'
Testing with Sandbox
When sandbox: true, all requests go to PayPal's sandbox environment. Use sandbox credentials from the PayPal Developer Dashboard.