--- tags: API Document --- New Subscribe API Flow === ## Complete PaymentIntent with user own existed card ### Step 1: List user's cards #### `GET` /api/v1/pay/payment_methods ##### Return ==HTTP 200== ```javascript= { "object": "list", "data": [ { "id": "card_1G7vbaHRhoOpWeKwOaPQB5Ok", "object": "payment_method", "billing_details": { "address": { "city": null, "country": null, "line1": null, "line2": null, "postal_code": null, "state": null }, "email": null, "name": null, "phone": null }, "card": { "brand": "visa", "checks": { "address_line1_check": null, "address_postal_code_check": null, "cvc_check": "pass" }, "country": "US", "exp_month": 12, "exp_year": 2029, "fingerprint": "Toy8qcIaG6LHoi95", "funding": "credit", "generated_from": null, "last4": "4242", "networks": { "available": [ "visa" ], "preferred": null }, "three_d_secure_usage": { "supported": true }, "wallet": null }, "created": 1580700490, "customer": "cus_DgdrtNVqfkTbCP", "livemode": false, "metadata": null, "type": "card" } ], "has_more": false, "url": "/v1/payment_methods" } ``` ### Step 2: Create PaymentIntent with existed card #### `POST` /api/v1/pay/plan/{plan_id}/new_subscribe ##### Body ```javascript= { "payment_method": "card_1G7vbaHRhoOpWeKwOaPQB5Ok" // Step 1 data.id } ``` ##### Returns ==HTTP 201== ```javascript= { "pid": 12, "plan": { "id": "reader-pro", // plan_id "period": "Monthly", "item": "reader-pro", "highlight": null, "amount": 7, "cny_amount": 101, "description": "for test", "is_online_sale": true, "cancel_at_period_end": false, "role": 20 }, "period": "Monthly", "id": "pi_W67Fynt3VCESxu", "customer": "cus_3Hk8QJGRH7fHIc", "create": "2020-08-04T05:40:36.219390Z", "client_secret": "pi_W67Fynt3VCESxu_secret_wNj1ActNzZKXr0j7", "setup_future_usage": null, "payment_method": "card_1G7vbaHRhoOpWeKwOaPQB5Ok", // This fields should not be null "user": 1 } ``` ## Complete PaymentIntent with user input card info Stripe new Payment Flow Document (https://stripe.com/docs/payments/payment-intents/migration) ### Step 1: Create new PaymentIntent #### `POST` /api/v1/pay/plan/{plan_id}/new_subscribe ##### Returns ==HTTP 201== ```javascript= { "pid": 13, "plan": { "id": "reader-pro", // plan_id "period": "Monthly", "item": "reader-pro", "highlight": null, "amount": 7, "cny_amount": 101, "description": "for test", "is_online_sale": true, "cancel_at_period_end": false, "role": 20 }, "period": "Monthly", "id": "pi_boXps0XxXsygWR", "customer": "cus_TiBaOKItI2iHrk", "create": "2020-08-04T05:19:47.218885Z", "client_secret": "pi_boXps0XxXsygWR_secret_LLJeg9o2ewHkxDb8", "setup_future_usage": null, "payment_method": null, "user": 1 } ``` ### Step 2: Use stripe package to confirm card payment Stripe JS library V3 Document (https://stripe.com/docs/js/including) ```javascript= stripe.confirmCardPayment( 'pi_boXps0XxXsygWR_secret_LLJeg9o2ewHkxDb8', // intent secret from step 1 { payment_method: {card: cardElement}, // card info from user input } ).then(function(result) { if (result.error) { // Display error.message in your UI. } else { // The payment has succeeded // Display a success message } }); ``` ## Complete PaymentIntent with user input card info and then save the card ### Step 1: Create new PaymentIntent #### `POST` /api/v1/pay/plan/{plan_id}/new_subscribe ##### Body ```javascript= { "setup_future_usage": "off_session" } ``` ##### Returns ==HTTP 201== ```javascript= { "pid": 13, "plan": { "id": "reader-pro", // plan_id "period": "Monthly", "item": "reader-pro", "highlight": null, "amount": 7, "cny_amount": 101, "description": "for test", "is_online_sale": true, "cancel_at_period_end": false, "role": 20 }, "period": "Monthly", "id": "pi_boXps0XxXsygWR", "customer": "cus_TiBaOKItI2iHrk", "create": "2020-08-04T05:19:47.218885Z", "client_secret": "pi_boXps0XxXsygWR_secret_LLJeg9o2ewHkxDb8", "setup_future_usage": "off_session", // This field will be change "payment_method": null, "user": 1 } ``` ### Step 2: Use stripe package to confirm card payment Stripe JS library V3 Document (https://stripe.com/docs/js/including) ```javascript= stripe.confirmCardPayment( 'pi_boXps0XxXsygWR_secret_LLJeg9o2ewHkxDb8', // intent secret from step 1 { payment_method: {card: cardElement}, // card info from user input } ).then(function(result) { if (result.error) { // Display error.message in your UI. } else { // The payment has succeeded // Display a success message } }); ``` --- ## Saving Card out side the Checkout Flow [Reference](https://stripe.com/docs/payments/payment-intents/migration#saved-cards) -> Saving cards outside checkout flow ### Step 1: Create a SetUpIntent #### `POST` /api/v1/pay/setup_intent ##### Return ```javascript= { "id": "seti_1HCbDtHRhoOpWeKwif80axHK", "object": "setup_intent", "application": null, "cancellation_reason": null, "client_secret": "seti_1HCbDtHRhoOpWeKwif80axHK_secret_Hm9WBW6Lvon5wZHz1Wpm3sQ180ZEGcn", "created": 1596590117, "customer": null, "description": null, "last_setup_error": null, "livemode": false, "mandate": null, "metadata": null, "next_action": null, "on_behalf_of": null, "payment_method": null, "payment_method_options": { "card": { "request_three_d_secure": "automatic" } }, "payment_method_types": [ "card" ], "single_use_mandate": null, "status": "requires_payment_method", "usage": "off_session" } ``` ### Step 2: Confirm the payment with card info ```javascript= stripe.confirmCardSetup( clientSecret, // seti_1HCbDtHRhoOpWeKwif80axHK_secret_Hm9WBW6Lvon5wZHz1Wpm3sQ180ZEGcn, from Step 1 { payment_method: { card: cardElement, // From user input billing_details: {name: cardholderName.value} } } ).then(function(result) { if (result.error) { // Display error.message in your UI. } else { // The SetupIntent was successful! } }); ``` ### Step 3: Notify backend to bind the payment #### `POST` /api/v1/pay/payment_methods #### Request Body ```javascript= { "payment_method": "pm_3cg0lkaP6iPEBg" // When confirmCardSetup succeeds, setupIntent.payment_method will contain a PaymentMethod that you can attach to a Customer. } ``` #### Return ==HTTP 201== ```javascript= { "billing_details": {}, "card": { "brand": "visa", "country": "FR", "exp_month": 12, "exp_year": 2060, "fingerprint": "79758cf4654d6cc6", "funding": "credit", "last4": "4242", "three_d_secure_usage": { "supported": true } }, "created": 1596589701, "customer": "cus_5YdTBotf5SVQB9", "id": "pm_3cg0lkaP6iPEBg", "livemode": false, "metadata": {}, "object": "payment_method", "type": "card" } ``` --- ## Change user default payment method ==Notice==: The daily job will charge the user's default payment method automatically when user accept the auto ### `PATCH` /api/v1/users/profiles/{id} #### Path Parameters - id - User's profile ID #### Request Body - default_payment_method - The user confirmed payment method ID #### Example ##### `PATCH` /api/v1/users/profiles/1 ##### Request Body ```javascript= { "default_payment_method": "pm_3cg0lkaP6iPEBg" } ``` ##### Return ==HTTP 200== ```javascript= { "id": 1, "user": "testuser", "name": null, "profile": 1, "email": "abc@abc.xyz", "role": "User", "role_id": 10, "capacity": 3, "mine_capacity": 3, "share_capacity": 3, "resource_capacity": 0, "resource_len": 0, "length": 1000, "tried": false, "end_role": null, "simple_count": 0, "traditional_count": 0, "share_simple_count": 0, "share_traditional_count": 0, "charset": "s", "image": null, "username": null, "sales_code": null, "onboarding": false, "language": "en", "uuid": null, "is_sent_valued_customer_coupon": false, "cancel_at_period_end": null, "last_succeed_payment_intent": null, "default_payment_method": "pm_3cg0lkaP6iPEBg", // Expect this field is as same as your input "levelsystem": 1, "account": null } ```