Stripe Payment Integration
This guide explains how to integrate Stripe payments into your application using our API.
Subscription Flow
1. Create a Subscription
First, create a subscription by calling the following mutation:
mutation CreatePayment {
stripeCreatePayment(
category: GROUP # Payment category (GROUP, MORE_LOGIN)
groupId: 21 # ID of the subscription group/plan
paymentMethodId: "pm_..." # Stripe Payment Method ID
renew: true # Whether this is a recurring subscription
) {
clientSecret
paymentIntentId
requiresAction
error
subscription {
id
status
currentPeriodEnd
cancelAtPeriodEnd
}
}
}
Response Structure
{
"data": {
"stripeCreatePayment": {
"clientSecret": string | null, // Used for 3D Secure authentication
"paymentIntentId": string | null, // Stripe Payment Intent ID
"requiresAction": boolean, // Whether additional action is needed
"error": string | null, // Error message if any
"subscription": {
"id": string, // Stripe Subscription ID
"status": string, // Subscription status
"currentPeriodEnd": string, // Subscription expiration date
"cancelAtPeriodEnd": boolean // Whether subscription will auto-renew
}
}
}
}
2. Handle Payment Confirmation
If requiresAction
is true
or the subscription status is incomplete
, you need to confirm the payment:
Using Stripe.js (Recommended)
// On your frontend
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret);
if (error) {
// Handle error
console.error("Payment failed:", error);
} else if (paymentIntent.status === "succeeded") {
// Payment successful, subscription should now be active
console.log("Payment successful!");
}
Using GraphQL
mutation ConfirmPayment {
stripeConfirmPayment(
paymentIntentId: "pi_..." # PaymentIntent ID from previous response
) {
clientSecret
paymentIntentId
requiresAction
error
subscription {
id
status
currentPeriodEnd
cancelAtPeriodEnd
}
}
}
Subscription Management
Update Subscription
Change a subscription's plan/group:
mutation UpdateSubscription {
stripeUpdateSubscription(
groupId: 22 # New group/plan ID
subscriptionId: "sub_..." # Stripe Subscription ID
) {
clientSecret
requiresAction
error
subscription {
id
status
currentPeriodEnd
cancelAtPeriodEnd
}
}
}
Cancel Subscription
Cancel an active subscription:
mutation CancelSubscription {
stripeCancelSubscription(
subscriptionId: "sub_..." # Stripe Subscription ID
)
}
Subscription Statuses
Status | Description |
---|---|
incomplete | Initial status, waiting for payment |
incomplete_expired | Initial payment failed |
active | Subscription is active |
past_due | Payment failed on renewal |
canceled | Subscription has been canceled |
unpaid | Payment failed and no retry scheduled |
Error Handling
The API returns errors in the following format:
{
"error": {
"message": "Error description",
"code": "error_code"
}
}
Common error codes:
card_declined
: The card was declinedexpired_card
: The card has expiredincorrect_cvc
: The CVC number is incorrectprocessing_error
: An error occurred while processing the cardinvalid_request
: The request was invalid
Webhook Events
The following webhook events are supported:
Event Type | Description |
---|---|
customer.subscription.created | New subscription created |
customer.subscription.updated | Subscription details updated |
customer.subscription.deleted | Subscription canceled |
invoice.payment_succeeded | Payment successful |
invoice.payment_failed | Payment failed |
Testing
Use these test card numbers:
Card Number | Description |
---|---|
4242424242424242 | Successful payment |
4000002500003155 | Requires authentication |
4000000000009995 | Payment declined |
tip
For testing 3D Secure authentication, use card number 4000002500003155 with any future expiry date and CVC.
caution
Always use test API keys in development and testing environments.
Best Practices
- Error Handling: Always handle both
error
andrequiresAction
responses. - Webhooks: Implement webhook handling for reliable payment status updates.
- Idempotency: Store and check payment IDs to prevent duplicate charges.
- Testing: Test all scenarios including 3D Secure and failed payments.
- Security: Never log or expose sensitive payment details.