---
# System prepended metadata

title: New Subscribe API Flow
tags: [API Document]

---

---
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
}
```