Skip to content

Payments

Payments

QZPay supports one-time payments, subscription charges, and refunds.

One-Time Payments

Basic Payment

const payment = await billing.payments.process({
customerId: 'cus_123',
amount: 9900, // Amount in cents
currency: 'USD',
paymentMethodId: 'pm_card_visa'
});

With Metadata

const payment = await billing.payments.process({
customerId: 'cus_123',
amount: 4900,
currency: 'USD',
paymentMethodId: 'pm_card_visa',
metadata: {
orderId: 'ord_123',
productId: 'prod_456'
}
});

Payment Status

StatusDescription
pendingPayment initiated, awaiting processing
processingBeing processed by provider
succeededPayment completed successfully
failedPayment failed
cancelledPayment was cancelled
refundedFully refunded
partially_refundedPartially refunded

Refunds

Full Refund

const refund = await billing.payments.refund({
paymentId: 'pay_123'
});

Partial Refund

const refund = await billing.payments.refund({
paymentId: 'pay_123',
amount: 2500, // Refund $25.00
reason: 'customer_request'
});

Payment Object

interface Payment {
id: string;
customerId: string;
subscriptionId?: string;
invoiceId?: string;
amount: number;
currency: string;
status: PaymentStatus;
paymentMethodId?: string;
description?: string;
metadata: Record<string, string>;
refundedAmount: number;
externalIds: Record<string, string>;
createdAt: Date;
updatedAt: Date;
}

Events

EventDescription
payment.succeededPayment completed successfully
payment.failedPayment failed
payment.refundedPayment was refunded
billing.on('payment.succeeded', async (event) => {
const { customerId, amount } = event.data;
await sendReceipt(customerId, amount);
});
billing.on('payment.failed', async (event) => {
await notifyPaymentFailure(event.data.customerId);
});

Error Handling

import { PaymentFailedError, CardDeclinedError } from '@qazuor/qzpay-core';
try {
await billing.payments.process({ ... });
} catch (error) {
if (error instanceof CardDeclinedError) {
// Ask customer to use different card
} else if (error instanceof PaymentFailedError) {
// Generic payment failure
}
}

Best Practices

  1. Always use idempotency keys for payment creation
  2. Store payment references in your order/transaction records
  3. Handle webhooks for payment status updates
  4. Implement retry logic for failed payments
  5. Log all payment events for audit purposes