# Get customer payment methods from Shopify Retrieves all payment methods associated with a customer directly from Shopify's payment API. This endpoint returns detailed information about stored payment instruments including credit/debit cards, digital wallets, and other payment methods that the customer can use for subscription billing. What This Endpoint Does: Queries Shopify's GraphQL API to fetch the customer's payment methods, including active instruments and optionally revoked (expired, removed, or failed) payment methods. This provides real-time payment method data directly from Shopify's payment vault. Payment Method Types Supported: Credit/Debit Cards: - Visa, Mastercard, American Express, Discover - Card last 4 digits - Expiry month and year - Card brand and type - Billing address associated with card Digital Wallets: - Shop Pay - Apple Pay - Google Pay - PayPal (when stored) Alternative Payment Methods: - Bank accounts (ACH, SEPA) - Buy Now Pay Later instruments - Store credit Payment Method Information Returned: For Each Payment Method: - Payment Instrument ID: Unique identifier (used for updates) - Display Name: Human-readable name (e.g., "Visa ending in 4242") - Payment Type: Card, wallet, bank account, etc. - Status: ACTIVE, REVOKED, EXPIRED, FAILED - Is Default: Whether this is the customer's default payment method - Last 4 Digits: For cards and bank accounts - Expiry Date: For cards (month/year) - Brand: Visa, Mastercard, Amex, etc. - Billing Address: Address associated with payment method - Created Date: When payment method was added Query Parameters: allowRevokedMethod (optional, default: false): - false: Returns only active, usable payment methods - true: Returns both active AND revoked payment methods Revoked Payment Methods: Include expired cards, deleted payment methods, failed instruments, and customer-removed methods. Useful for historical records and troubleshooting, but cannot be used for new billing attempts. Use Cases: 1. Customer Portal: - Display saved payment methods - Allow customer to select default payment method - Show payment method update/delete options - Validate payment methods before subscription modification 2. Subscription Management: - Verify customer has valid payment method before creating subscription - Check payment method expiry before next billing - Identify subscriptions at risk due to expiring cards - Prompt customer to update payment if needed 3. Payment Method Updates: - List available payment methods for customer selection - Identify payment instrument ID for update operations - Validate payment method before switching subscription 4. Troubleshooting & Support: - Debug payment failures - Verify which payment method is being used - Check if payment method is expired or revoked - Assist customer with payment issues 5. Analytics & Alerts: - Track payment methods approaching expiry - Send proactive notifications to update cards - Analyze payment method distribution - Identify customers with no valid payment methods Response Structure: Returns CustomerPaymentMethodsQuery.PaymentMethods object from Shopify GraphQL: json { "nodes": [ { "id": "gid://shopify/CustomerPaymentMethod/abc123", "instrument": { "__typename": "CustomerCreditCard", "brand": "VISA", "lastDigits": "4242", "expiryMonth": 12, "expiryYear": 2025, "name": "John Doe" }, "revokedAt": null, "revokedReason": null, "subscriptionContracts": [...] } ] } Common Scenarios: Scenario 1: Customer with multiple cards Returns array with multiple payment method objects, each representing a stored card. Scenario 2: Customer with no payment methods Returns empty nodes array - customer needs to add payment method. Scenario 3: Expired card included (allowRevokedMethod=true) Returns both active cards and expired/revoked cards with revokedAt timestamp. Important Considerations: Data Source: - Queries Shopify API in real-time (not Appstle database) - Always returns current Shopify payment method state - Subject to Shopify API rate limits Performance: - Response time: 300-800ms (depends on Shopify API) - Slower than database queries - Consider caching for non-critical displays Security: - Never returns full card numbers (PCI compliance) - Returns only last 4 digits - CVV is never stored or returned - Payment instrument IDs are tokenized references Privacy: - Customer ID validated against shop - Cannot query payment methods from other shops - Requires appropriate API permissions Best Practices: 1. Default to Active Only: Use allowRevokedMethod=false for payment selection UIs 2. Check Expiry Dates: Validate card expiry before using for subscriptions 3. Cache Responsibly: Cache for short periods (5-10 min) to reduce API calls 4. Handle Empty Response: Always handle case where customer has no payment methods 5. Show User-Friendly Names: Display brand and last 4 (e.g., "Visa •••• 4242") 6. Indicate Default: Highlight the default payment method clearly Integration Examples: Example 1: Display payment methods in customer portal javascript const paymentMethods = await fetch( /api/external/v2/subscription-contract-details/shopify/customer/${customerId}/payment-methods, { headers: { 'X-API-Key': 'your-key' } } ).then(r => r.json()); paymentMethods.nodes.forEach(pm => { if (pm.instrument.__typename === 'CustomerCreditCard') { console.log(${pm.instrument.brand} ending in ${pm.instrument.lastDigits}); if (pm.instrument.expiryYear !pm.revokedAt && pm.instrument.expiryYear >= currentYear ); if (!hasValidPayment) { alert('Please add a valid payment method before subscribing'); } Related Endpoints: - PUT /api/external/v2/subscription-contracts-update-payment-method - Update subscription payment method - POST /api/external/v2/associate-shopify-customer-to-external-payment-gateways - Add external payment method Authentication: Requires valid X-API-Key header Endpoint: GET /api/external/v2/subscription-contract-details/shopify/customer/{customerId}/payment-methods Version: 0.0.1 ## Header parameters: - `X-API-Key` (string) ## Path parameters: - `customerId` (integer, required) Customer Id ## Query parameters: - `allowRevokedMethod` (boolean) Get revoked payment methods? ## Response 200 fields (application/json): - `get__typename` (string) - `nodes` (array) - `nodes.id` (string) - `nodes.sellingPlanId` (string) - `nodes.sellingPlanName` (string) - `nodes.productId` (string) - `nodes.sku` (string) - `nodes.title` (string) - `nodes.variantId` (string) - `nodes.quantity` (integer) - `nodes.customAttributes` (array) - `nodes.customAttributes.key` (string) - `nodes.customAttributes.value` (string) - `nodes.lineDiscountedPrice` (object) - `nodes.lineDiscountedPrice.amount` (object) - `nodes.lineDiscountedPrice.currencyCode` (string) Enum: "USD", "EUR", "GBP", "CAD", "AFN", "ALL", "DZD", "AOA", "ARS", "AMD", "AWG", "AUD", "BBD", "AZN", "BDT", "BSD", "BHD", "BIF", "BYN", "BZD", "BMD", "BTN", "BAM", "BRL", "BOB", "BWP", "BND", "BGN", "MMK", "KHR", "CVE", "KYD", "XAF", "CLP", "CNY", "COP", "KMF", "CDF", "CRC", "HRK", "CZK", "DKK", "DJF", "DOP", "XCD", "EGP", "ERN", "ETB", "FKP", "XPF", "FJD", "GIP", "GMD", "GHS", "GTQ", "GYD", "GEL", "GNF", "HTG", "HNL", "HKD", "HUF", "ISK", "INR", "IDR", "ILS", "IRR", "IQD", "JMD", "JPY", "JEP", "JOD", "KZT", "KES", "KID", "KWD", "KGS", "LAK", "LVL", "LBP", "LSL", "LRD", "LYD", "LTL", "MGA", "MKD", "MOP", "MWK", "MVR", "MRU", "MXN", "MYR", "MUR", "MDL", "MAD", "MNT", "MZN", "NAD", "NPR", "ANG", "NZD", "NIO", "NGN", "NOK", "OMR", "PAB", "PKR", "PGK", "PYG", "PEN", "PHP", "PLN", "QAR", "RON", "RUB", "RWF", "WST", "SHP", "SAR", "RSD", "SCR", "SLL", "SGD", "SDG", "SOS", "SYP", "ZAR", "KRW", "SSP", "SBD", "LKR", "SRD", "SZL", "SEK", "CHF", "TWD", "THB", "TJS", "TZS", "TOP", "TTD", "TND", "TRY", "TMT", "UGX", "UAH", "AED", "UYU", "UZS", "VUV", "VES", "VND", "XOF", "YER", "ZMW", "USDC", "BYR", "STD", "STN", "VED", "VEF", "XXX", "$UNKNOWN" - `nodes.variantImage` (object) - `nodes.variantImage.transformedSrc` (object) - `nodes.variantTitle` (string) - `nodes.currentPrice` (object) - `nodes.discountAllocations` (array) - `nodes.discountAllocations.discount` (object) - `nodes.pricingPolicy` (object) - `nodes.pricingPolicy.basePrice` (object) - `nodes.pricingPolicy.cycleDiscounts` (array) - `nodes.pricingPolicy.cycleDiscounts.afterCycle` (integer) - `nodes.pricingPolicy.cycleDiscounts.computedPrice` (object) - `nodes.pricingPolicy.cycleDiscounts.adjustmentType` (string) Enum: "PERCENTAGE", "FIXED_AMOUNT", "PRICE", "$UNKNOWN" - `nodes.pricingPolicy.cycleDiscounts.adjustmentValue` (object) - `nodes.taxable` (boolean) - `pageInfo` (object) - `pageInfo.hasPreviousPage` (boolean) - `pageInfo.hasNextPage` (boolean) - `pageInfo.startCursor` (string) - `pageInfo.endCursor` (string) ## Response 400 fields ## Response 401 fields ## Response 403 fields ## Response 404 fields ## Response 429 fields ## Response 502 fields