# Accept subscription payments with PayTo Learn how to create and charge for a subscription with PayTo. Use this guide to set up a *subscription* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) using [PayTo](https://docs.stripe.com/payments/payto.md) as a payment method. # Stripe-hosted page You can use the [Checkout API](https://docs.stripe.com/api/checkout/sessions.md) to create and confirm a subscription with a prebuilt checkout page. ## Create a product and price [Dashboard] [Products](https://docs.stripe.com/api/products.md) represent the item or service you’re selling. [Prices](https://docs.stripe.com/api/prices.md) define how much and how frequently you charge for a product. This includes how much the product costs, what currency you accept, and whether it’s a one-time or recurring charge. If you only have a few products and prices, create and manage them in the Dashboard. This guide uses a stock photo service as an example and charges customers a 15 AUD monthly subscription. To model this: 1. Go to the [Products](https://dashboard.stripe.com/products?active=true) page and click **Create product**. 2. Enter a **Name** for the product. You can optionally add a **Description** and upload an image of the product. 3. Select a **Product tax code**. Learn more about [product tax codes](https://docs.stripe.com/tax/tax-codes.md). 4. Select **Recurring**. Then enter **15** for the price and select **AUD** as the currency. 5. Choose whether to **Include tax in price**. You can either use the default value from your [tax settings](https://dashboard.stripe.com/test/settings/tax) or set the value manually. In this example, select **Auto**. 6. Select **Monthly** for the **Billing period**. 7. Click **More pricing options**. Then select **Flat rate** as the pricing model for this example. Learn more about [flat rate](https://docs.stripe.com/products-prices/pricing-models.md#flat-rate) and other [pricing models](https://docs.stripe.com/products-prices/pricing-models.md). 8. Add an internal **Price description** and [Lookup key](https://docs.stripe.com/products-prices/manage-prices.md#lookup-keys) to organize, query, and update specific prices in the future. 9. Click **Next**. Then click **Add product**. After you create the product and the price, record the price ID so you can use it in subsequent steps. The pricing page displays the ID and it looks similar to this: `price_G0FvDp6vZvdwRZ`. ## Create a Checkout Session [Server-side] Your customer must authorize you to use their bank account for future payments through Stripe Checkout. This allows you to accept PayTo payments. Add a checkout button to your website that calls a server-side endpoint to create a [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md). ```html Checkout
``` Create a Checkout Session in `subscription` mode to collect the required information. After creating the Checkout Session, redirect your customer to the [URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) that the response returns. Limit the amount on your mandates by setting `amount` in the `payment_method_options` as several banks [always reject mandates without an amount specified](https://docs.stripe.com/payments/payto.md#bank-limits). ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ --data-urlencode "success_url=https://example.com/success" \ -d "line_items[0][price]={{RECURRING_PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d "payment_method_options[payto][mandate_options][amount]=1500" \ -d mode=subscription ``` ## Test your integration Test your PayTo integration with your test API keys by using the various test PayIDs and bank account details below. Each set of details results in a different scenario your integration might commonly face in live mode. #### PayID | PayID | Description | | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}+succeed@{any_domain}` | The PaymentIntent status transitions from `requires_action` to `processing` after 10 seconds, then transitions to `succeeded` after an additional 5 seconds. The mandate enters an `active` state. | | `{any_prefix}+decline@{any_domain}` | The PaymentIntent status transitions from `requires_action` to `requires_payment_method` after 10 seconds. Stripe returns the `payment_method_provider_decline` error code and an `invalid_authorization` decline code. The mandate enters an `inactive` state. | | `{any_prefix}+expire@{any_domain}` | The PaymentIntent status transitions from `requires_action` to `requires_payment_method` after 10 seconds. Stripe returns the `payment_method_provider_decline` error code and a `generic_decline` decline code. The mandate enters an `inactive` state. | | `{any_prefix}+insufficient_funds@{any_domain}` | The PaymentIntent status transitions from `requires_action` to `processing` after 10 seconds, then transitions to `requires_payment_method` after an additional 5 seconds. Stripe returns the `payment_method_provider_decline` error code and an `insufficient_funds` decline code. The mandate enters an `inactive` state. | | `{any_prefix}+revoke@{any_domain}` | The PaymentIntent status transitions from `requires_action` to `processing` after 10 seconds then to `succeeded` after a further 5 seconds. The mandate begins in an `active` state and transitions to `inactive` after 1 minute. | | `{any_prefix}+agreement_type_not_supported@{any_domain}` | The PaymentIntent status transitions from `requires_action` to `requires_payment_method` after 10 seconds. Stripe returns the `payment_method_provider_decline` error code. The mandate enters an `inactive` state. | #### Account + BSB numbers | BSB number | Account number | Description | | ---------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `000000` | `000123456` | The PaymentIntent status transitions from `requires_action` to `processing` after 10 seconds, then transitions to `succeeded` after an additional 5 seconds. The mandate enters an `active` state. | | `000000` | `333333335` | The PaymentIntent status transitions from `requires_action` to `requires_payment_method` after 10 seconds. Stripe returns the `payment_method_provider_decline` error code and an `invalid_authorization` decline code. The mandate enters an `inactive` state. | | `000000` | `333333337` | The PaymentIntent status transitions from `requires_action` to `requires_payment_method` after 10 seconds. Stripe returns the `payment_method_provider_decline` error code and a `generic_decline` decline code. The mandate enters an `inactive` state. | | `000000` | `222222227` | The PaymentIntent status transitions from `requires_action` to `processing` after 10 seconds, then transitions to `requires_payment_method` after an additional 5 seconds. Stripe returns the `payment_method_provider_decline` error code and an `insufficient_funds` decline code. The mandate enters an `inactive` state. | | `000000` | `444444447` | The PaymentIntent status transitions from `requires_action` to `processing` after 10 seconds, then transitions to `succeeded` after an additional 5 seconds. The mandate begins in an `active` state and transitions to `inactive` after 1 minute. | | `000000` | `666666667` | The PaymentIntent status transitions from `requires_action` to `requires_payment_method` after 10 seconds. Stripe returns the `payment_method_provider_decline` error code. The mandate enters an `inactive` state. |