# Retry billing for failed attempt Immediately triggers a billing attempt for a subscription contract, bypassing the normal scheduled billing time. This endpoint processes the billing asynchronously via Shopify's Subscription Billing API, creating an order and charging the customer's payment method. How Billing Retry Works: 1. Validation: Checks if shop has enableImmediatePlaceOrder permission (premium feature) 2. Async Trigger: Queues billing job in background (returns immediately) 3. Shopify API Call: Sends subscriptionBillingAttemptCreate mutation to Shopify 4. Payment Processing: Charges customer's stored payment method 5. Order Creation: Creates Shopify order if payment succeeds 6. Notification: Sends order confirmation email to customer (if enabled) 7. Webhook Events: Triggers SUBSCRIPTION_BILLING_ATTEMPTS_SUCCESS or _FAILURE webhook When to Use This Endpoint: - Payment Failed Previously: Customer updated credit card, retry failed billing - Scheduled Too Far Out: Customer wants early delivery, bill before scheduled date - Payment Method Updated: Customer just added new payment method, retry immediately - Manual Recovery: Merchant intervention to recover failed subscription - Testing/QA: Validate subscription billing flow in test environments - Customer Request: Expedited order fulfillment for urgent needs Important Limitations & Restrictions: - Permission Required: Only available to shops with enableImmediatePlaceOrder permission - This is a premium feature - free plans will receive 400 error - Upgrade subscription plan in Appstle admin to enable - Rate Limiting: Maximum 5 billing attempts per contract per hour (anti-abuse) - Billing Attempt Status: Can retry attempts with status QUEUED, SCHEDULED, or FAILED - Cannot Retry: Billing attempts with status SUCCESS (order already created) - Duplicate Prevention: Shopify prevents duplicate orders within 24-hour window - Payment Method Required: Contract must have valid payment method attached Asynchronous Processing Details: This endpoint returns immediately (200 OK) before billing completes. Actual billing happens in background: - Success Response: Means billing job was queued, NOT that payment succeeded - Actual Result: Check via webhooks or poll /subscription-billing-attempts endpoint - Processing Time: Typically 5-30 seconds depending on Shopify API response time - Timeout Handling: Background job retries up to 3 times if Shopify API times out Checking Billing Result (Recommended Flow): Step 1: Call this endpoint to trigger billing PUT /subscription-billing-attempts/attempt-billing/123456 Response: 200 OK (billing queued) Step 2: Wait 10-15 seconds for processing Step 3: Poll billing attempt status GET /subscription-billing-attempts?id=123456 Check 'status' field: - SUCCESS: Order created, payment captured - FAILED: Payment declined or error occurred - PROCESSING: Still in progress, poll again Step 4: (Alternative) Use webhooks for real-time updates Configure webhook: SUBSCRIPTION_BILLING_ATTEMPTS_SUCCESS Receive notification when billing completes Common Error Scenarios: - 400 - Permission Denied: "You don't have permission to place immediate orders" - Solution: Upgrade to premium plan with enableImmediatePlaceOrder feature - 400 - Rate Limit: "Too many billing attempts. Maximum 5 per hour per contract." - Solution: Wait before retrying, investigate why billing keeps failing - 400 - Invalid Status: "Cannot retry billing attempt with status SUCCESS" - Solution: Order already created successfully, check order history - 404 - Not Found: "Billing attempt not found" - Solution: Verify billing attempt ID belongs to this shop - 500 - Shopify API Error: Background job may fail if Shopify API is down - Solution: Retry after 5 minutes, check Shopify status page Payment Failure Reasons (Check After Async Processing): After billing processes, if status becomes FAILED, common reasons include: - Card Declined: Insufficient funds, expired card, fraud detection - Invalid Payment Method: Customer deleted payment method - 3D Secure Failed: Authentication challenge not completed - Gateway Error: Payment processor (Stripe/Shopify Payments) issue - Inventory Shortage: Product out of stock, cannot fulfill order - Subscription Canceled: Contract canceled between retry trigger and processing Integration Best Practices: 1. Always Check Permission First: Call /shop-info or similar to verify feature access 2. Implement Webhooks: Don't rely on polling - use webhooks for real-time status 3. User Communication: Warn user "Billing in progress..." since it's async 4. Idempotency: Safe to call multiple times - Shopify prevents duplicate orders 5. Error Handling: Gracefully handle permission errors for free plan users 6. Logging: Track billing attempt ID for troubleshooting and support Example Use Case - Customer Portal: Scenario: Customer's card declined, they updated payment method 1. Customer sees "Payment Failed" in portal 2. Customer clicks "Update Payment Method" → adds new card 3. Customer clicks "Retry Payment Now" button 4. Frontend calls: PUT /subscription-billing-attempts/attempt-billing/789 5. Display: "Processing payment..." spinner 6. Poll endpoint every 5 seconds for status update 7. On SUCCESS: Show "Payment successful! Order #12345 created." 8. On FAILED: Show decline reason + retry instructions Difference from Skip/Reschedule: - Attempt Billing: Immediately charges customer and creates order NOW - Skip: Postpones order to next billing cycle, no charge - Reschedule: Changes billing date without triggering immediate charge Authentication: Requires API key authentication via X-API-Key header or api_key parameter. Additionally requires merchant account to have enableImmediatePlaceOrder permission (premium feature). Endpoint: PUT /api/external/v2/subscription-billing-attempts/attempt-billing/{id} Version: 0.0.1 ## Path parameters: - `id` (integer, required) Billing attempt ID to retry Example: 123456 ## Query parameters: - `api_key` (string) API Key (Deprecated - Use Header X-API-Key instead) ## Header parameters: - `X-API-Key` (string) ## Response 200 fields ## Response 400 fields ## Response 401 fields ## Response 404 fields ## Response 500 fields