@spree/docs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -0
- package/dist/api-reference/platform/authentication.md +38 -0
- package/dist/api-reference/store-api/authentication.md +188 -0
- package/dist/api-reference/store-api/errors.md +277 -0
- package/dist/api-reference/store-api/idempotency.md +129 -0
- package/dist/api-reference/store-api/introduction.md +34 -0
- package/dist/api-reference/store-api/localization.md +279 -0
- package/dist/api-reference/store-api/metadata.md +160 -0
- package/dist/api-reference/store-api/monetary-amounts.md +65 -0
- package/dist/api-reference/store-api/querying.md +399 -0
- package/dist/api-reference/store-api/rate-limitting.md +103 -0
- package/dist/api-reference/store-api/relations.md +185 -0
- package/dist/api-reference/storefront/authentication.md +88 -0
- package/dist/api-reference/tutorials/adyen-integration-guide-for-android.md +165 -0
- package/dist/api-reference/tutorials/adyen-integration-guide-for-ios.md +194 -0
- package/dist/api-reference/tutorials/quick-checkout-with-stripe.md +248 -0
- package/dist/api-reference/v2/fetching-multiple-resources.md +26 -0
- package/dist/api-reference/v2/filtering-and-sorting.md +53 -0
- package/dist/api-reference/v2/introduction.md +22 -0
- package/dist/api-reference/v2/pagination.md +37 -0
- package/dist/api-reference/webhooks-events.md +883 -0
- package/dist/developer/admin/admin.md +205 -0
- package/dist/developer/admin/authentication.md +59 -0
- package/dist/developer/admin/components.md +711 -0
- package/dist/developer/admin/custom-css.md +243 -0
- package/dist/developer/admin/custom-javascript.md +116 -0
- package/dist/developer/admin/extending-ui.md +1964 -0
- package/dist/developer/admin/form-builder.md +444 -0
- package/dist/developer/admin/helper-methods.md +531 -0
- package/dist/developer/admin/navigation.md +805 -0
- package/dist/developer/admin/tables.md +491 -0
- package/dist/developer/advanced/adding_spree_to_rails_app.md +106 -0
- package/dist/developer/cli/quickstart.md +137 -0
- package/dist/developer/contributing/creating-an-extension.md +258 -0
- package/dist/developer/contributing/developing-spree.md +339 -0
- package/dist/developer/contributing/quickstart.md +32 -0
- package/dist/developer/contributing/updating-extensions.md +67 -0
- package/dist/developer/core-concepts/addresses.md +265 -0
- package/dist/developer/core-concepts/adjustments.md +107 -0
- package/dist/developer/core-concepts/architecture.md +177 -0
- package/dist/developer/core-concepts/calculators.md +323 -0
- package/dist/developer/core-concepts/customers.md +230 -0
- package/dist/developer/core-concepts/events.md +624 -0
- package/dist/developer/core-concepts/imports-exports.md +698 -0
- package/dist/developer/core-concepts/inventory.md +191 -0
- package/dist/developer/core-concepts/markets.md +250 -0
- package/dist/developer/core-concepts/media.md +167 -0
- package/dist/developer/core-concepts/metafields.md +187 -0
- package/dist/developer/core-concepts/orders.md +328 -0
- package/dist/developer/core-concepts/payments.md +710 -0
- package/dist/developer/core-concepts/pricing.md +163 -0
- package/dist/developer/core-concepts/products.md +360 -0
- package/dist/developer/core-concepts/promotions.md +322 -0
- package/dist/developer/core-concepts/reports.md +206 -0
- package/dist/developer/core-concepts/search-filtering.md +237 -0
- package/dist/developer/core-concepts/shipments.md +212 -0
- package/dist/developer/core-concepts/slugs.md +111 -0
- package/dist/developer/core-concepts/staff-roles.md +123 -0
- package/dist/developer/core-concepts/store-credits-gift-cards.md +317 -0
- package/dist/developer/core-concepts/stores.md +117 -0
- package/dist/developer/core-concepts/taxes.md +135 -0
- package/dist/developer/core-concepts/translations.md +120 -0
- package/dist/developer/core-concepts/users.md +299 -0
- package/dist/developer/core-concepts/webhooks.md +378 -0
- package/dist/developer/create-spree-app/quickstart.md +158 -0
- package/dist/developer/customization/api.md +93 -0
- package/dist/developer/customization/authentication.md +88 -0
- package/dist/developer/customization/checkout.md +204 -0
- package/dist/developer/customization/configuration.md +55 -0
- package/dist/developer/customization/decorators.md +523 -0
- package/dist/developer/customization/dependencies.md +232 -0
- package/dist/developer/customization/emails.md +21 -0
- package/dist/developer/customization/extensions.md +92 -0
- package/dist/developer/customization/metadata.md +236 -0
- package/dist/developer/customization/model-preferences.md +130 -0
- package/dist/developer/customization/permissions.md +265 -0
- package/dist/developer/customization/quickstart.md +229 -0
- package/dist/developer/customization/routes.md +24 -0
- package/dist/developer/customization/v4/admin-panel.md +78 -0
- package/dist/developer/customization/v4/authentication.md +210 -0
- package/dist/developer/customization/v4/checkout.md +212 -0
- package/dist/developer/customization/v4/deface.md +251 -0
- package/dist/developer/customization/v4/images.md +86 -0
- package/dist/developer/customization/v4/storefront.md +450 -0
- package/dist/developer/deployment/assets.md +87 -0
- package/dist/developer/deployment/aws.md +335 -0
- package/dist/developer/deployment/caching.md +27 -0
- package/dist/developer/deployment/cdn.md +39 -0
- package/dist/developer/deployment/database.md +155 -0
- package/dist/developer/deployment/docker.md +128 -0
- package/dist/developer/deployment/emails.md +77 -0
- package/dist/developer/deployment/environment_variables.md +111 -0
- package/dist/developer/deployment/heroku.md +51 -0
- package/dist/developer/deployment/render.md +95 -0
- package/dist/developer/getting-started/quickstart.md +82 -0
- package/dist/developer/how-to/custom-payment-method.md +374 -0
- package/dist/developer/how-to/custom-promotion.md +373 -0
- package/dist/developer/how-to/custom-report.md +387 -0
- package/dist/developer/how-to/custom-search-provider.md +230 -0
- package/dist/developer/multi-store/quickstart.md +71 -0
- package/dist/developer/multi-store/setup.md +38 -0
- package/dist/developer/multi-tenant/configuration.md +41 -0
- package/dist/developer/multi-tenant/core-concepts.md +75 -0
- package/dist/developer/multi-tenant/installation.md +96 -0
- package/dist/developer/multi-tenant/quickstart.md +20 -0
- package/dist/developer/multi-vendor/installation.md +45 -0
- package/dist/developer/multi-vendor/quickstart.md +17 -0
- package/dist/developer/sdk/admin/quickstart.md +22 -0
- package/dist/developer/sdk/authentication.md +89 -0
- package/dist/developer/sdk/configuration.md +225 -0
- package/dist/developer/sdk/quickstart.md +82 -0
- package/dist/developer/sdk/store/account.md +67 -0
- package/dist/developer/sdk/store/cart-checkout.md +140 -0
- package/dist/developer/sdk/store/markets.md +151 -0
- package/dist/developer/sdk/store/payments.md +96 -0
- package/dist/developer/sdk/store/products.md +149 -0
- package/dist/developer/sdk/store/wishlists.md +52 -0
- package/dist/developer/security/pci_compliance.md +15 -0
- package/dist/developer/security/security_policy.md +68 -0
- package/dist/developer/storefront/blocks.md +285 -0
- package/dist/developer/storefront/custom-css.md +260 -0
- package/dist/developer/storefront/custom-javascript.md +166 -0
- package/dist/developer/storefront/helper-methods.md +1288 -0
- package/dist/developer/storefront/links.md +298 -0
- package/dist/developer/storefront/nextjs/architecture.md +150 -0
- package/dist/developer/storefront/nextjs/customization.md +141 -0
- package/dist/developer/storefront/nextjs/deployment.md +180 -0
- package/dist/developer/storefront/nextjs/quickstart.md +92 -0
- package/dist/developer/storefront/nextjs/spree-next-package.md +314 -0
- package/dist/developer/storefront/pages.md +163 -0
- package/dist/developer/storefront/sections.md +569 -0
- package/dist/developer/storefront/storefront.md +56 -0
- package/dist/developer/storefront/themes.md +161 -0
- package/dist/developer/tutorial/admin.md +134 -0
- package/dist/developer/tutorial/extending-models.md +380 -0
- package/dist/developer/tutorial/file-uploads.md +121 -0
- package/dist/developer/tutorial/introduction.md +33 -0
- package/dist/developer/tutorial/model.md +41 -0
- package/dist/developer/tutorial/page-builder.md +487 -0
- package/dist/developer/tutorial/rich-text.md +73 -0
- package/dist/developer/tutorial/seo.md +332 -0
- package/dist/developer/tutorial/storefront.md +352 -0
- package/dist/developer/tutorial/testing.md +558 -0
- package/dist/developer/upgrades/2.0-to-2.1.md +46 -0
- package/dist/developer/upgrades/2.1-to-2.2.md +59 -0
- package/dist/developer/upgrades/2.2-to-2.3.md +44 -0
- package/dist/developer/upgrades/2.3-to-2.4.md +42 -0
- package/dist/developer/upgrades/3.0-to-3.1.md +47 -0
- package/dist/developer/upgrades/3.1-to-3.2.md +34 -0
- package/dist/developer/upgrades/3.2-to-3.3.md +70 -0
- package/dist/developer/upgrades/3.3-to-3.4.md +36 -0
- package/dist/developer/upgrades/3.4-to-3.5.md +44 -0
- package/dist/developer/upgrades/3.5-to-3.6.md +40 -0
- package/dist/developer/upgrades/3.6-to-3.7.md +62 -0
- package/dist/developer/upgrades/3.7-to-4.0.md +152 -0
- package/dist/developer/upgrades/4.0-to-4.1.md +92 -0
- package/dist/developer/upgrades/4.1-to-4.2.md +109 -0
- package/dist/developer/upgrades/4.10-to-5.0.md +129 -0
- package/dist/developer/upgrades/4.2-to-4.3.md +100 -0
- package/dist/developer/upgrades/4.3-to-4.4.md +125 -0
- package/dist/developer/upgrades/4.4-to-4.5.md +94 -0
- package/dist/developer/upgrades/4.5-to-4.6.md +119 -0
- package/dist/developer/upgrades/4.6-to-4.7.md +39 -0
- package/dist/developer/upgrades/4.8-to-4.9.md +24 -0
- package/dist/developer/upgrades/4.9-to-4.10.md +24 -0
- package/dist/developer/upgrades/4.x-to-4.8.md +52 -0
- package/dist/developer/upgrades/5.0-to-5.1.md +28 -0
- package/dist/developer/upgrades/5.1-to-5.2.md +127 -0
- package/dist/developer/upgrades/5.2-to-5.3.md +338 -0
- package/dist/developer/upgrades/5.3-to-5.4.md +248 -0
- package/dist/developer/upgrades/quickstart.md +36 -0
- package/dist/integrations/analytics/google-analytics.md +64 -0
- package/dist/integrations/analytics/google-tag-manager.md +78 -0
- package/dist/integrations/integrations.md +39 -0
- package/dist/integrations/marketing/klaviyo.md +99 -0
- package/dist/integrations/payments/adyen.md +90 -0
- package/dist/integrations/payments/paypal.md +41 -0
- package/dist/integrations/payments/razorpay.md +45 -0
- package/dist/integrations/payments/stripe.md +109 -0
- package/dist/integrations/search/meilisearch.md +236 -0
- package/dist/integrations/sso-mfa-social-login/admin-dashboard.md +57 -0
- package/dist/integrations/sso-mfa-social-login/storefront.md +56 -0
- package/package.json +27 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Authentication
|
|
3
|
+
description: Learn how to authenticate requests to the Storefront API.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Storefront API requires authorization only for certain actions associated with user account (e.g. updating saved addresses) or manipulating cart and checkout.
|
|
7
|
+
|
|
8
|
+
## For guest users
|
|
9
|
+
|
|
10
|
+
### Using X-Spree-Order-Token header
|
|
11
|
+
|
|
12
|
+
[Cart](/api-reference/storefront/cart) and [Checkout](/api-reference/storefront/checkout) endpoints paths also allow interactions without the bearer token to allow creating and managing guest checkouts.
|
|
13
|
+
|
|
14
|
+
When you first create a cart via:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
curl --request POST \
|
|
18
|
+
--url 'https://demo.spreecommerce.org/api/v2/storefront/cart?fields%5Bcart%5D=number%2Ctoken' \
|
|
19
|
+
--header 'Content-Type: application/vnd.api+json'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
You'll receive a response containing an empty cart. This response also contains a `data.token` attribute.
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"data": {
|
|
27
|
+
"id": "114",
|
|
28
|
+
"type": "cart",
|
|
29
|
+
"attributes": {
|
|
30
|
+
"number": "R522550303",
|
|
31
|
+
"token": "NswjLVjZOw4OpEm1yWqlJg1713367317414"
|
|
32
|
+
},
|
|
33
|
+
"relationships": {}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
You can store this token in the frontend session (eg. Session Storage or a cookie) and pass it in a `X-Spree-Order-Token: {token}` header.
|
|
39
|
+
|
|
40
|
+
## For signed in users
|
|
41
|
+
|
|
42
|
+
For users who have an account in your store, you will need to generate oAuth tokens to authenticate requests to endpoints such as [Account](/api-reference/storefront/account), [Cart](/api-reference/storefront/cart) and [Checkout](/api-reference/storefront/checkout).
|
|
43
|
+
|
|
44
|
+
### Generating OAuth token
|
|
45
|
+
|
|
46
|
+
To obtain a token, execute the following curl command:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -X POST http://localhost:3000/spree_oauth/token \
|
|
50
|
+
--header "Content-Type: application/x-www-form-urlencoded" \
|
|
51
|
+
--data "grant_type=password&username=spree@example.com&password=spree123"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
You should receive a JSON response with a `access_token` and a `refresh_token`, eg.
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"access_token": "CmVXoDp6f5Y51s2xFAAdSbdT5wcGZIuGKKr27zAkBvQ",
|
|
59
|
+
"token_type": "Bearer",
|
|
60
|
+
"expires_in": 7200,
|
|
61
|
+
"refresh_token": "g5xPzY51_QYyok-ZcH9f4_btBkT_RZ6pB7ugGRaMjQQ",
|
|
62
|
+
"created_at": 1713367848
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Refreshing OAuth token
|
|
67
|
+
|
|
68
|
+
OAuth tokens obtained via the previous step are valid only for a specific time (defined in `expires_in` attribute).
|
|
69
|
+
|
|
70
|
+
After that period, you can refresh the token by executing the following curl command:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
curl -X POST http://localhost:3000/spree_oauth/token \
|
|
74
|
+
--header "Content-Type: application/x-www-form-urlencoded" \
|
|
75
|
+
--data "grant_type=refresh_token&refresh_token=g5xPzY51_QYyok-ZcH9f4_btBkT_RZ6pB7ugGRaMjQQ"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
On a success, you'll receive a new bearer token to use when accessing the API, eg.
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"access_token": "JVMcaoCkxV4o2xofhAwf7ReeFEWUM94ZnVSKRITd3TQ",
|
|
83
|
+
"token_type": "Bearer",
|
|
84
|
+
"expires_in": 7200,
|
|
85
|
+
"refresh_token": "nMlyfxfA9U6xfSDnFhoZQzL4IOkDc-EkW1y66ZTf5Oc",
|
|
86
|
+
"created_at": 1713367950
|
|
87
|
+
}
|
|
88
|
+
```
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Adyen Integration Guide for Android
|
|
3
|
+
description: This guide provides step-by-step instructions for integrating Adyen Android Drop-in with spree_adyen using session flow and Drop-In component.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **WARNING:** This guide is aimed at advanced users who want to create adyen integration for their custom android application.
|
|
7
|
+
> You also need to install Spree Adyen extension before.
|
|
8
|
+
|
|
9
|
+
## Note
|
|
10
|
+
|
|
11
|
+
The list of available library versions can be found on [Official Adyen Documentation for Android integration](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/?platform=Android&integration=Drop-in&version=5.13.1)
|
|
12
|
+
Current newest version available at the moment of writing the tutorial is 5.13.1.
|
|
13
|
+
This doc will be referring to the library version as YOUR_VERSION.
|
|
14
|
+
|
|
15
|
+
## Resources
|
|
16
|
+
|
|
17
|
+
- [Official Adyen Documentation for Android integration](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/?platform=Android&integration=Drop-in&version=5.13.1)
|
|
18
|
+
- Spree Adyen API docs - [create payment_session](/api-reference/storefront/adyen/create-an-adyen-payment-session) and [get payment_session](/api-reference/storefront/adyen/get-adyen-payment-session)
|
|
19
|
+
- [Official Adyen example for Android integration](https://github.com/adyen-examples/adyen-android-online-payments)
|
|
20
|
+
|
|
21
|
+
## Overview
|
|
22
|
+
|
|
23
|
+
The integration consists of two main components:
|
|
24
|
+
|
|
25
|
+
- **Spree Adyen**: Provides API for your client and receive payment result from Adyen
|
|
26
|
+
- **Your Android client app**: Shows the Drop-in UI and handles payment flow
|
|
27
|
+
|
|
28
|
+
## Step 1: Import the library
|
|
29
|
+
|
|
30
|
+
Import the compatibility module:
|
|
31
|
+
|
|
32
|
+
### Import the module with Jet Compose
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
implementation "com.adyen.checkout:drop-in-compose:YOUR_VERSION"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Import without Jet Compose
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
implementation "com.adyen.checkout:drop-in:YOUR_VERSION"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Step 2: Create a checkout session
|
|
45
|
+
|
|
46
|
+
Create session using [this endpoint](/api-reference/storefront/adyen/create-an-adyen-payment-session).
|
|
47
|
+
|
|
48
|
+
```kotlin
|
|
49
|
+
val sessionModel = SessionModel.SERIALIZER.deserialize(sessionsResponseJSON)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
sessionsResponseJSON should contain:
|
|
53
|
+
- `sessionData` - available as `adyen_data` in payment_session API response
|
|
54
|
+
- `id` - available as `adyen_id` in payment_session API response
|
|
55
|
+
|
|
56
|
+
```kotlin
|
|
57
|
+
val sessionModel = SessionModel.SERIALIZER.deserialize(sessionsResponseJSON)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Step 3
|
|
61
|
+
|
|
62
|
+
call `CheckoutSessionProvider.createSession` passing serialized session data (`sessionModel`) and `dropInConfiguration`
|
|
63
|
+
|
|
64
|
+
dropInConfiguration example:
|
|
65
|
+
|
|
66
|
+
```kotlin
|
|
67
|
+
val checkoutConfiguration = CheckoutConfiguration(
|
|
68
|
+
environment = environment,
|
|
69
|
+
clientKey = clientKey,
|
|
70
|
+
shopperLocale = shopperLocale, // Optional
|
|
71
|
+
) {
|
|
72
|
+
// Optional: add Drop-in configuration.
|
|
73
|
+
dropIn {
|
|
74
|
+
setEnableRemovingStoredPaymentMethods(true)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Optional: add or change default configuration for the card payment method.
|
|
78
|
+
card {
|
|
79
|
+
setHolderNameRequired(true)
|
|
80
|
+
setShopperReference("...")
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Optional: change configuration for 3D Secure 2.
|
|
84
|
+
adyen3DS2 {
|
|
85
|
+
setThreeDSRequestorAppURL("...")
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
see also: https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/?platform=Web&integration=Drop-in&version=6.18.1#create-instance
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
`environment` - enum: `live` or `test`
|
|
93
|
+
`clientKey` - `client_key` from payment_sessions endpoint
|
|
94
|
+
`shopperLocale` - shopper locale in ISO format
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
```kotlin
|
|
98
|
+
// Create an object for the checkout session.
|
|
99
|
+
val result = CheckoutSessionProvider.createSession(sessionModel, dropInConfiguration)
|
|
100
|
+
|
|
101
|
+
// If the payment session is successful, handle the result.
|
|
102
|
+
// If the payment session encounters an error, handle the error.
|
|
103
|
+
when (result) {
|
|
104
|
+
is CheckoutSessionResult.Success -> handleCheckoutSession(result.checkoutSession)
|
|
105
|
+
is CheckoutSessionResult.Error -> handleError(result.exception)
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Step 4: Launch and show Drop-in
|
|
110
|
+
|
|
111
|
+
```kotlin
|
|
112
|
+
override fun onDropInResult(sessionDropInResult: SessionDropInResult?) {
|
|
113
|
+
when (sessionDropInResult) {
|
|
114
|
+
// The payment finishes with a result.
|
|
115
|
+
is SessionDropInResult.Finished -> handleResult(sessionDropInResult.result)
|
|
116
|
+
// The shopper dismisses Drop-in.
|
|
117
|
+
is SessionDropInResult.CancelledByUser ->
|
|
118
|
+
// Drop-in encounters an error.
|
|
119
|
+
is SessionDropInResult.Error -> handleError(sessionDropInResult.reason)
|
|
120
|
+
// Drop-in encounters an unexpected state.
|
|
121
|
+
null ->
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Step 5: Create the Drop-in launcher
|
|
127
|
+
|
|
128
|
+
DropIn.startPayment, passing:
|
|
129
|
+
|
|
130
|
+
- `dropInLauncher` - The Drop-in launcher object
|
|
131
|
+
- `checkoutSession` - result of `CheckoutSessionProvider.createSession`
|
|
132
|
+
- `dropInConfiguration` - Your Drop-in configuration
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
|
|
136
|
+
```kotlin
|
|
137
|
+
import com.adyen.checkout.dropin.compose.startPayment
|
|
138
|
+
import com.adyen.checkout.dropin.compose.rememberLauncherForDropInResult
|
|
139
|
+
|
|
140
|
+
@Composable
|
|
141
|
+
private fun ComposableDropIn() {
|
|
142
|
+
val dropInLauncher = rememberLauncherForDropInResult(sessionDropInCallback)
|
|
143
|
+
|
|
144
|
+
DropIn.startPayment(dropInLauncher, checkoutSession, dropInConfiguration)
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Get payment outcome
|
|
149
|
+
|
|
150
|
+
1. Wait for backend to process the payment
|
|
151
|
+
2. Continue shopping experience
|
|
152
|
+
|
|
153
|
+
### 1. Wait for backend to process the payment
|
|
154
|
+
|
|
155
|
+
backend will change the state of `payment_session` to one of the following state
|
|
156
|
+
|
|
157
|
+
- `pending` - chosen payment method can take a while to complete
|
|
158
|
+
- `completed` - payment resulted in success, order completed
|
|
159
|
+
- `canceled` - payment canceled, payment is `void`
|
|
160
|
+
- `refused` - payment failed
|
|
161
|
+
|
|
162
|
+
### 2. Continue shopping experience
|
|
163
|
+
|
|
164
|
+
if succeed - order is processed and completed
|
|
165
|
+
if failed - payment can be retried using new payment session
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Adyen Integration Guide for iOS
|
|
3
|
+
description: This guide provides step-by-step instructions for integrating Adyen iOS Drop-in with spree_adyen using session flow and Drop-In component.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **WARNING:** This guide is aimed at advanced users who want to create adyen integration for their custom iOS application.
|
|
7
|
+
> You also need to install Spree Adyen extension before.
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- Adyen test account
|
|
12
|
+
- Set up `spree_adyen` spree extension
|
|
13
|
+
|
|
14
|
+
### return_url
|
|
15
|
+
|
|
16
|
+
spree_adyen needs to be configured with `return_url`.
|
|
17
|
+
|
|
18
|
+
Return url tells where shopper should be redirect after the payment from outside your application (for example klarna or most of others buy now pay later systems).
|
|
19
|
+
|
|
20
|
+
Use the custom URL for your app, like `my-app://adyen`. Url can contain custom query params however do not include any personally identifiable information (PII) of your customer. Maximum length of the url is 1024 characters.
|
|
21
|
+
|
|
22
|
+
## Note
|
|
23
|
+
|
|
24
|
+
The list of available library versions can be found on [Official Adyen Documentation for iOS integration](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/?platform=iOS&integration=Drop-in&version=5.13.1)
|
|
25
|
+
Current newest version available at the moment of writing the tutorial is 5.19.2.
|
|
26
|
+
|
|
27
|
+
## Resources
|
|
28
|
+
|
|
29
|
+
- [Official Adyen Documentation for iOS integration](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/?platform=iOS&integration=Drop-in&version=5.19.2)
|
|
30
|
+
- Spree Adyen API docs - [create payment_session](/api-reference/storefront/adyen/create-an-adyen-payment-session) and [get payment_session](/api-reference/storefront/adyen/get-adyen-payment-session)
|
|
31
|
+
- [Official Adyen example for iOS integration](https://github.com/Adyen/adyen-ios/tree/develop/Demo)
|
|
32
|
+
- Apple Developer documentation on [defining custom url scheme](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app)
|
|
33
|
+
|
|
34
|
+
## Overview
|
|
35
|
+
|
|
36
|
+
The integration consists of two main components:
|
|
37
|
+
|
|
38
|
+
- **Spree Adyen**: Provides API for your client and receive payment result from Adyen
|
|
39
|
+
- **Your iOS client app**: Shows the Drop-in UI and handles payment flow
|
|
40
|
+
|
|
41
|
+
## Step 1: Install adyen with Swift Package Manager
|
|
42
|
+
|
|
43
|
+
repository URL:
|
|
44
|
+
```
|
|
45
|
+
https://github.com/Adyen/adyen-ios
|
|
46
|
+
```
|
|
47
|
+
use at least version 5.0.0
|
|
48
|
+
|
|
49
|
+
CocoaPods and Carthage instructions are available [here](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow/?platform=iOS&integration=Drop-in&version=5.19.2&tab=cocoapods_1_2#1-get-adyen-ios).
|
|
50
|
+
|
|
51
|
+
## Step 2: Create the context
|
|
52
|
+
|
|
53
|
+
Create the instance of APIContext that includes client key and environment setting.
|
|
54
|
+
|
|
55
|
+
```swift
|
|
56
|
+
// Set the client key and environment in an instance of APIContext.
|
|
57
|
+
let apiContext = APIContext(clientKey: clientKey, environment: Environment.test) // Set the environment to a live one when going live.
|
|
58
|
+
// Create the amount with the value in minor units and the currency code.
|
|
59
|
+
let amount = Amount(value: 1000, currencyCode: "EUR")
|
|
60
|
+
// Create the payment object with the amount and country code.
|
|
61
|
+
let payment = Payment(amount: amount, countryCode: "NL")
|
|
62
|
+
// Create an instance of AdyenContext, passing the instance of APIContext, and payment object.
|
|
63
|
+
let adyenContext = AdyenContext(apiContext: apiContext, payment:payment)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`environment` - Environment.test or Environment.live
|
|
67
|
+
`clientKey` - `client_key` from payment_sessions endpoint
|
|
68
|
+
|
|
69
|
+
## Step 3: Create and set up session
|
|
70
|
+
|
|
71
|
+
Create a session using [payment_session endpoint](/api-reference/storefront/adyen/create-an-adyen-payment-session).
|
|
72
|
+
Then set a configuration using data from the response:
|
|
73
|
+
|
|
74
|
+
```swift
|
|
75
|
+
let configuration = AdyenSession.Configuration(sessionIdentifier: sessionId,
|
|
76
|
+
initialSessionData: data)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- `data` - available as `adyen_data` in payment_session API response
|
|
80
|
+
- `sessionId` - available as `adyen_id` in payment_session API response
|
|
81
|
+
|
|
82
|
+
With the configuration you initialize AdyenSession:
|
|
83
|
+
|
|
84
|
+
```swift
|
|
85
|
+
AdyenSession.initialize(with: configuration, delegate: self, presentationDelegate: self) { [weak self] result in
|
|
86
|
+
switch result {
|
|
87
|
+
case let .success(session):
|
|
88
|
+
//Store the session object.
|
|
89
|
+
self?.session = session
|
|
90
|
+
case let .failure(error):
|
|
91
|
+
//Handle the error.
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Step 4. Configure Drop-in
|
|
97
|
+
|
|
98
|
+
```swift
|
|
99
|
+
let dropInConfiguration = DropInComponent.Configuration()
|
|
100
|
+
// Some payment methods have additional required or optional configuration.
|
|
101
|
+
// For example, an optional configuration to show the cardholder name field for cards.
|
|
102
|
+
dropInConfiguration.card.showsHolderNameField = true
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Step 5: Initialize the DropInComponent class
|
|
106
|
+
|
|
107
|
+
```swift
|
|
108
|
+
let dropInComponent = DropInComponent(paymentMethods: session.sessionContext.paymentMethods,
|
|
109
|
+
context: adyenContext,
|
|
110
|
+
configuration: dropInConfiguration)
|
|
111
|
+
|
|
112
|
+
// Keep the instance of Drop-in to so that it doesn't get destroyed after the function is executed.
|
|
113
|
+
self.dropInComponent = dropInComponent
|
|
114
|
+
|
|
115
|
+
// Set the session as the delegate.
|
|
116
|
+
dropInComponent.delegate = session
|
|
117
|
+
// If you support gift cards, set the session as the partial payment delegate.
|
|
118
|
+
dropInComponent.partialPaymentDelegate = session
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Step 6: Show Drop-in in your app
|
|
122
|
+
|
|
123
|
+
```swift
|
|
124
|
+
myCheckoutViewController.present(dropInComponent.viewController, animated: true)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
If the `action` field is `redirect` you need to handle the redirect result.
|
|
128
|
+
|
|
129
|
+
## Step 7. Handling the redirect result
|
|
130
|
+
|
|
131
|
+
If the `action` field returns `redirect` the shopper is completing the payment outside of your application. You need to inform the Drop-in when the shopper returns to your app.
|
|
132
|
+
|
|
133
|
+
Here an example for a Custom Url scheme:
|
|
134
|
+
- implement the following in your `UIApplicationDelegate`:
|
|
135
|
+
|
|
136
|
+
```swift
|
|
137
|
+
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
|
|
138
|
+
return RedirectComponent.applicationDidOpen(from: url)
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
for Universal URL use this instead:
|
|
143
|
+
```swift
|
|
144
|
+
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
|
|
145
|
+
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
|
|
146
|
+
let incomingURL = userActivity.webpageURL else { return false }
|
|
147
|
+
return RedirectComponent.applicationDidOpen(from: incomingURL)
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Step 8: Show the shopper result of the payment
|
|
152
|
+
|
|
153
|
+
When the payment flow is finished, your instance of AdyenSession calls the didComplete method.
|
|
154
|
+
Implement the following in your Drop-in configuration object.
|
|
155
|
+
|
|
156
|
+
```swift
|
|
157
|
+
func didComplete(with result: AdyenSessionResult, // The session result.
|
|
158
|
+
component: Component, // The Drop-in component.
|
|
159
|
+
session: AdyenSession) // Your instance of AdyenSession.
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Use the resultCode to inform your shopper about the current payment status.
|
|
163
|
+
Possible resultCode values:
|
|
164
|
+
- `authorised` - payment authorised
|
|
165
|
+
- `refused` - payment refused
|
|
166
|
+
- `pending` - payment pending (for payments with asynchronous flow like iDEAL). When the shopper completes the payment webhook will process process the payment.
|
|
167
|
+
- `cancelled` - payment canceled
|
|
168
|
+
- `received` - some payments needs more time to be processed. When the status is available webhook will process the payment
|
|
169
|
+
- `error` - an error occurred when processing the payment. The response contains more details with the error code
|
|
170
|
+
Your instance of AdyenSession calls the didFail method containing the error.
|
|
171
|
+
```swift
|
|
172
|
+
func didFail(with error: Error, // The error object.
|
|
173
|
+
from component: Component, // The Drop-in component.
|
|
174
|
+
session: AdyenSession) // Your instance of AdyenSession.
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Step 8: Continue shopping experience
|
|
178
|
+
|
|
179
|
+
1. Wait for backend to process the payment
|
|
180
|
+
2. Continue shopping experience
|
|
181
|
+
|
|
182
|
+
### 1. Wait for backend to process the payment
|
|
183
|
+
|
|
184
|
+
backend after receiving webhook will change the state of `payment_session` to one of the following state:
|
|
185
|
+
- `pending` - chosen payment method can take a while to complete
|
|
186
|
+
- `completed` - payment resulted in success, order completed
|
|
187
|
+
- `canceled` - payment canceled, payment is `void`
|
|
188
|
+
- `refused` - payment failed
|
|
189
|
+
|
|
190
|
+
### 2. Continue shopping experience
|
|
191
|
+
|
|
192
|
+
if succeed - order is processed and completed
|
|
193
|
+
|
|
194
|
+
if failed - payment can be retried using new payment session
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Quick Checkout with Stripe and Storefront API
|
|
3
|
+
description: This tutorial will show you how to add quick checkout to your headless/composable storefront using Stripe and Spree APIs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> **WARNING:** This guide is aimed at advanced users who have some experience with Spree API and Stripe.
|
|
7
|
+
> You also need to install [Spree Stripe](https://github.com/spree/spree_stripe) extension before.
|
|
8
|
+
|
|
9
|
+
> **INFO:** If you're using the standard Spree Storefront, then you can skip this tutorial as quick checkout is already built in.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
Assume that you have a cart made with line items in it already.
|
|
14
|
+
|
|
15
|
+
Quick checkout works by handling 3 different events:
|
|
16
|
+
- Address change
|
|
17
|
+
- Shipping Method/Rate change
|
|
18
|
+
- Confirmation
|
|
19
|
+
|
|
20
|
+
How you should handle them depends on your platform/language:
|
|
21
|
+
|
|
22
|
+
- For Web and JS, please review:
|
|
23
|
+
- [Express Checkout Element](https://docs.stripe.com/elements/express-checkout-element)
|
|
24
|
+
- We also recommend reviewing the [spree_stripe implementation in Stimulus.js](https://github.com/spree/spree_stripe/blob/main/app/javascript/spree_stripe/controllers/stripe_button_controller.js)
|
|
25
|
+
|
|
26
|
+
- For iOS, please review:
|
|
27
|
+
- [StripeApplePay](https://docs.stripe.com/apple-pay)
|
|
28
|
+
- [STPApplePayContext](https://stripe.dev/stripe-ios/stripeapplepay/documentation/stripeapplepay/stpapplepaycontext#instance-methods)
|
|
29
|
+
|
|
30
|
+
## Checkout Flow
|
|
31
|
+
|
|
32
|
+
### Address change
|
|
33
|
+
|
|
34
|
+
Here we need to send some basic information about the customer's shipping address, and we should move the order to the delivery step (don't forget to replace the placeholders with the customer's data):
|
|
35
|
+
|
|
36
|
+
<details>
|
|
37
|
+
<summary>Update the checkout</summary>
|
|
38
|
+
|
|
39
|
+
```bash Update order [expandable]
|
|
40
|
+
curl -X PATCH <SHOP URL>/api/v2/storefront/checkout \
|
|
41
|
+
-H 'Authorization: Bearer <Token>' \
|
|
42
|
+
-H 'Content-Type: application/json' \
|
|
43
|
+
-d '{
|
|
44
|
+
"order": {
|
|
45
|
+
"ship_address_attributes": {
|
|
46
|
+
"quick_checkout": true,
|
|
47
|
+
"firstname": <First name>,
|
|
48
|
+
"lastname": <Last name>,
|
|
49
|
+
"city": <City>,
|
|
50
|
+
"zipcode": <Zip>,
|
|
51
|
+
"country_iso": <Country>,
|
|
52
|
+
"state_name": <State>
|
|
53
|
+
},
|
|
54
|
+
"bill_address_id": "CLEAR"
|
|
55
|
+
}
|
|
56
|
+
}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- **`quick_checkout`** (`bool`) — `true` indicating that the order is from quick checkout. It is required as the address details you will receive from Apple Pay or Google Pay are not complete and wouldn't be valid for the standard checkout.
|
|
60
|
+
|
|
61
|
+
- **`firstname`** (`string`) — Customer's first name, e.g. John
|
|
62
|
+
|
|
63
|
+
- **`lastname`** (`string`) — Customer's last name, e.g. Doe
|
|
64
|
+
|
|
65
|
+
- **`city`** (`string`) — Customer's city, e.g. Mountain View
|
|
66
|
+
|
|
67
|
+
- **`zipcode`** (`string`) — Customer's zip code, e.g. 94043
|
|
68
|
+
|
|
69
|
+
- **`country_iso`** (`string`) — Customer's country ISO, e.g. US
|
|
70
|
+
|
|
71
|
+
- **`state_name`** (`string`) — Customer's address state, e.g. CA (empty string is also accepted)
|
|
72
|
+
|
|
73
|
+
- **`bill_address_id`** (`string`) — Set it to `CLEAR` to clear the existing billing address (this prevents the order from accidentally advancing to the `payment` step).
|
|
74
|
+
|
|
75
|
+
[Full documentation](/api-reference/storefront/checkout/update-checkout)
|
|
76
|
+
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
<details>
|
|
80
|
+
<summary>Move the order to the delivery step</summary>
|
|
81
|
+
|
|
82
|
+
[Endpoint documentation](/api-reference/storefront/checkout-state/advance-checkout)
|
|
83
|
+
|
|
84
|
+
```bash Advance order to the delivery step
|
|
85
|
+
curl -X PATCH '<SHOP URL>/api/v2/storefront/checkout/advance?state=delivery&include=shipments.shipping_rates' \
|
|
86
|
+
-H 'Authorization: Bearer <Token>' \
|
|
87
|
+
-H 'Content-Type: application/json' \
|
|
88
|
+
-d '{
|
|
89
|
+
"quick_checkout": true,
|
|
90
|
+
"shipping_method_id": <Shipping Method ID>
|
|
91
|
+
}'
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- **`quick_checkout`** (`bool`) — `true` indicating that the order is from quick checkout
|
|
95
|
+
|
|
96
|
+
- **`shipping_method_id`** (`string`) — You don't have to send `shipping_method_id` if you don't have it yet, but if you received `Shipping Method/Rate changed` event, and you already have the selected shipping method, then you can send it.
|
|
97
|
+
|
|
98
|
+
This will return you an order response, and you can update the payment element with a new total (you should use `total_minus_store_credits` for total) and shipping rates.
|
|
99
|
+
|
|
100
|
+
</details>
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
### Shipping Method/Rate change
|
|
104
|
+
|
|
105
|
+
Here we need to send the selected shipping method to the backend and update the total in the payment element
|
|
106
|
+
|
|
107
|
+
[Endpoint documentation](/api-reference/storefront/checkout-shipments/selects-shipping-method-for-shipments)
|
|
108
|
+
|
|
109
|
+
```bash Select shipping method
|
|
110
|
+
curl -X PATCH '<SHOP URL>/api/v2/storefront/checkout/select_shipping_method' \
|
|
111
|
+
-H 'Authorization: Bearer <Token>' \
|
|
112
|
+
-H 'Content-Type: application/json' \
|
|
113
|
+
-d '{
|
|
114
|
+
"shipping_method_id": <Shipping Method ID>
|
|
115
|
+
}'
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- **`shipping_method_id`** (`string`) — Shipping method ID of the selected shipping rate
|
|
119
|
+
|
|
120
|
+
Subsequently, update the payment element with a new total taken from the response's `total_minus_store_credits`
|
|
121
|
+
|
|
122
|
+
### Confirming the payment
|
|
123
|
+
|
|
124
|
+
Now you should make several more calls to the backend
|
|
125
|
+
|
|
126
|
+
<details>
|
|
127
|
+
<summary>Confirm that the order is ready for the payment</summary>
|
|
128
|
+
|
|
129
|
+
```bash Validate order for payment
|
|
130
|
+
curl -X POST '<SHOP URL>/api/v2/storefront/checkout/validate_order_for_payment?skip_state=true' \
|
|
131
|
+
-H 'Authorization: Bearer <Token>'
|
|
132
|
+
```
|
|
133
|
+
> **INFO:** `200` response code means that the order is ready for the payment.
|
|
134
|
+
|
|
135
|
+
[Endpoint documentation](/api-reference/storefront/checkout/validate-order-payment)
|
|
136
|
+
|
|
137
|
+
</details>
|
|
138
|
+
|
|
139
|
+
<details>
|
|
140
|
+
<summary>Update the address with more data</summary>
|
|
141
|
+
|
|
142
|
+
You should have a lot more information about the customer (in previous events, Stripe probably will not provide you information such as customer address), so send them to the backend:
|
|
143
|
+
|
|
144
|
+
[Endpoint documentation](/api-reference/storefront/checkout/update-checkout)
|
|
145
|
+
|
|
146
|
+
```bash Update the order [expandable]
|
|
147
|
+
curl -X PATCH <SHOP URL>/api/v2/storefront/checkout \
|
|
148
|
+
-H 'Authorization: Bearer <Token>' \
|
|
149
|
+
-H 'Content-Type: application/json' \
|
|
150
|
+
-d '{
|
|
151
|
+
"order": {
|
|
152
|
+
"email": <EMAIL>,
|
|
153
|
+
"ship_address_attributes": {
|
|
154
|
+
"quick_checkout": true,
|
|
155
|
+
"firstname": <First name>,
|
|
156
|
+
"lastname": <Last name>,
|
|
157
|
+
"address1": <Address>,
|
|
158
|
+
"address2": <Address 2>,
|
|
159
|
+
"city": <City>,
|
|
160
|
+
"zipcode": <Zip>,
|
|
161
|
+
"country_iso": <Country>,
|
|
162
|
+
"state_name": <State>,
|
|
163
|
+
"phone": <Phone>
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"do_not_change_state": true
|
|
167
|
+
}'
|
|
168
|
+
```
|
|
169
|
+
- **`email`** (`string`) — Customer's email, e.g. email@example.com
|
|
170
|
+
|
|
171
|
+
- **`quick_checkout`** (`bool`) — `true` indicating that the order is from quick checkout
|
|
172
|
+
|
|
173
|
+
- **`firstname`** (`string`) — Customer's first name, e.g. John
|
|
174
|
+
|
|
175
|
+
- **`lastname`** (`string`) — Customer's last name, e.g. Doe
|
|
176
|
+
|
|
177
|
+
- **`address1`** (`string`) — Customer's address, e.g. 123 Main St
|
|
178
|
+
|
|
179
|
+
- **`address2`** (`string`) — Customer's address 2, e.g., Apt. 1
|
|
180
|
+
|
|
181
|
+
- **`zipcode`** (`string`) — Customer's zip code, e.g. 94043
|
|
182
|
+
|
|
183
|
+
- **`country_iso`** (`string`) — Customer's country ISO, e.g. US
|
|
184
|
+
|
|
185
|
+
- **`state_name`** (`string`) — Customer's address state, e.g. CA (empty string is also accepted)
|
|
186
|
+
|
|
187
|
+
- **`phone`** (`string`) — Customer's phone number, e.g. +1234567890
|
|
188
|
+
|
|
189
|
+
- **`do_not_change_state`** (`bool`) — Set it to `true` so the order does not advance to the next state
|
|
190
|
+
|
|
191
|
+
</details>
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
<details>
|
|
195
|
+
<summary>Move the order to the payment step</summary>
|
|
196
|
+
|
|
197
|
+
[Endpoint documentation](/api-reference/storefront/checkout-state/advance-checkout)
|
|
198
|
+
```bash Move the order to the payment step
|
|
199
|
+
curl -X PATCH '<SHOP URL>/api/v2/storefront/checkout/advance?state=payment' \
|
|
200
|
+
-H 'Authorization: Bearer <Token>' \
|
|
201
|
+
-d '{
|
|
202
|
+
"shipping_method_id": <Shipping Method ID>
|
|
203
|
+
}'
|
|
204
|
+
```
|
|
205
|
+
- **`shipping_method_id`** (`string`) — Shipping method ID of the selected shipping rate
|
|
206
|
+
|
|
207
|
+
</details>
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
Thereafter, you should confirm the payment intent using the Stripe library; this depends on your platform/language.
|
|
211
|
+
|
|
212
|
+
> **WARNING:** `<PAYMENT INTENT ID>` should be Spree's internal payment intent ID, which you will receive when you create the payment intent. Do not confuse it with Stripe's payment intent ID.
|
|
213
|
+
|
|
214
|
+
If you like to redirect the user to Spree's order summary page, then set the `return_url` when confirming the payment intent to `<SHOP URL>/stripe/payment_intents/<PAYMENT INTENT ID>`. This will check if the payment intent is confirmed, move the order to the complete state, and redirect the user to the order summary.
|
|
215
|
+
|
|
216
|
+
If you like to make the order summary page by yourself, then after confirming the payment intent in Stripe, make this request:
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
```bash Confirm payment intent
|
|
220
|
+
curl -X POST <SHOP URL>/api/v2/storefront/stripe/payment_intents/<PAYMENT INTENT ID>/confirm \
|
|
221
|
+
-H 'Authorization: Bearer <Token>'
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
[Endpoint documentation](/api-reference/storefront/stripe/mark-the-payment-intent-as-confirmed-and-move-the-order-to-the-complete-state)
|
|
225
|
+
|
|
226
|
+
This will also check if the payment intent is confirmed, and it will move the order to the complete state
|
|
227
|
+
|
|
228
|
+
### User cancels the payment
|
|
229
|
+
|
|
230
|
+
If at any point, the user cancels the payment (closes the quick checkout sheet/modal), you will need to handle this event and clear the shipping and billing address from the order as these addresses will not be valid and if someones decides to use standard checkout it could lead to errors.
|
|
231
|
+
|
|
232
|
+
```bash Reset order addresses
|
|
233
|
+
curl -X PATCH <SHOP URL>/api/v2/storefront/checkout \
|
|
234
|
+
-H 'Authorization: Bearer <Token>' \
|
|
235
|
+
-H 'Content-Type: application/json' \
|
|
236
|
+
-d '{
|
|
237
|
+
"order": {
|
|
238
|
+
"ship_address_id": "CLEAR",
|
|
239
|
+
"bill_address_id": "CLEAR"
|
|
240
|
+
}
|
|
241
|
+
}'
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
[Endpoint documentation](/api-reference/storefront/checkout/update-checkout)
|
|
245
|
+
|
|
246
|
+
### All Done!
|
|
247
|
+
|
|
248
|
+
Congrats! Now, your users should be able to pay for orders with quick checkout! Need support or want to give some feedback? You can join our [community](https://slack.spreecommerce.org/) or drop us an email at [hello@spreecommerce.org](mailto:hello@spreecommerce.org).
|