Skip to content

Commit

Permalink
Add documentation for V3
Browse files Browse the repository at this point in the history
  • Loading branch information
tir38 committed Sep 30, 2024
1 parent 9e0a126 commit baafca6
Show file tree
Hide file tree
Showing 4 changed files with 469 additions and 26 deletions.
102 changes: 102 additions & 0 deletions docs/getting-started/checkout-v3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
---
layout: default
title: Checkout V3
parent: Getting Started
nav_order: 5
---

# Checkout V3
{: .no_toc }

<details markdown="block" open>
<summary>
Table of contents
</summary>
{: .text-delta }
- TOC
{:toc}
</details>


{: .alert }
> Checkout V3 is currently available in the following region(s): US, UK, Australia and Canada
>
Checkout V3 generates a one-time payment card for every Afterpay order and provides the card number to insert into your credit card checkout. This allows for a front-end-only integration. Unlike V1 and V2, with V3 your server does not directly interact with Afterpay APIs. The one-time payment card is Visa for the US, UK, and Canada. In Australia the one-time payment card is Mastercard.

## How it works

The transaction uses a one-time virtual payment card, which has a unique card number. Once the virtual card exists, you use it to handle authorization, capture, and refunds. Your integration is simplified, as you don’t have to integrate with additional endpoints.

{: .note }
Always set V3 Configuration before presentation, otherwise you will incur an assertionFailure. See the **Set Configuration** section below.

## Step 1: Set the V3 Configuration


```kotlin
Afterpay.setConfigurationV3(
CheckoutV3Configuration(
shopDirectoryMerchantId = "your_merchant_id",
region = AfterpayRegion.US,
environment = AfterpayEnvironment.PRODUCTION,
)
)
```

## Step 2: Start checkout on button click

On button click, start the checkout dialog by creating an `Intent` and launching `Activity` for result:

```kotlin
val intent =
Afterpay.createCheckoutV3Intent(
context = view.context,
consumer = // TODO create customer object,
orderTotal = // TODO create order total,
items = // TODO create list of items,
configuration = // TODO required if you didn't previously call setConfigurationV3(),
)
activityResultLauncher.launch(intent)

```
## Step 3: Listen for Activity result

Results will contain either a `RESULT_OK` or `RESULT_CANCELED`. Parse the response with either `Afterpay.parseCheckoutSuccessResponseV3` or `Afterpay.parseCheckoutCancellationResponseV3` respectively.

```kotlin
private val activityResultLauncher =
registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
) { result: ActivityResult ->
val intent = result.data
checkNotNull(intent)
if (result.resultCode == RESULT_OK) {
Afterpay.parseCheckoutSuccessResponseV3(intent)?.let {
// TODO next step
}
} else if (result.resultCode == RESULT_CANCELED) {
Afterpay.parseCheckoutCancellationResponseV3(intent)
?.let {
(
cancellationStatusV3: CancellationStatusV3,
exception: Exception?,
),
->
Log.e(tag, cancellationStatusV3.toString(), exception)
}
}
}
```

## Step 4: Receive one-time use card details and pass back to your server for processing

The success result will contain card details, tokens, and a valid-until time. Pass these back to your own server and process them through your normal card processing infrastructure.

```kotlin
Afterpay.parseCheckoutSuccessResponseV3(intent)?.let {
// pass card details and token to your server for processing with
// your existing card processing network
it.cardDetails
it.tokens
it.cardValidUntil
```
9 changes: 7 additions & 2 deletions docs/getting-started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ nav_order: 3

# Getting Started

Getting started with the SDK involves configuring the SDK with the response from the `/configuration` API endpoint as well as selecting and implementing a checkout method (V1 or V2).
[Checkout V1][checkout-v1] requires a url to be generated using the checkout API and using it to start the intent provided by the SDK.

[Checkout V1][checkout-v1] requires a url to be generated using the checkout API and using it to start the intent provided by the SDK. [Checkout V2][checkout-v2] requires setting options of type `AfterpayCheckoutV2Options` and creating handler methods for user interactions.
[Checkout V2][checkout-v2] requires setting options of type `AfterpayCheckoutV2Options` and creating handler methods for user interactions.

Both V1 and V2 involves configuring the SDK with the response from the `/configuration` API endpoint as well as selecting and implementing a checkout method (V1 or V2).

[Checkout V3][checkout-v3] does not require direct SDK interaction with `/configuration` API endpoint.

[checkout-v1]: checkout-v1
[checkout-v2]: checkout-v2
[checkout-v3]: checkout-v3
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
layout: default
title: Cash App Pay
title: Checkout V2 with Cash App Pay
parent: Getting Started
nav_order: 4
---

# Cash App Pay
# Checkout V2 with Cash App Pay
{: .d-inline-block .no_toc }
NEW (v4.3.0)
{: .label .label-green }
Expand All @@ -31,7 +31,7 @@ With our latest enhancements, you can now support taking Cash App Pay payments u
## Step 1: Import the Cash App Pay Kit Dependency

You can get the the latest version of the SDK from Maven. This is the import definition using Gradle:
You can get the latest version of the SDK from Maven. This is the import definition using Gradle:

```gradle
implementation "app.cash.paykit:core:2.3.0"
Expand All @@ -40,7 +40,7 @@ implementation "app.cash.paykit:core:2.3.0"
For definitions of other build systems, see [Cash App Pay Kit on Maven Central][cash-on-maven]{:target="_blank"}.

{: .info }
> Version `v2.3.0` of the SDK size is `12.3 kB`.
> Version `v2.3.0` of the SDK is `12.3 kB`.
## Step 2: Create a Cash App Pay Kit SDK Instance

Expand All @@ -49,7 +49,6 @@ To create a new instance of the Cash App Pay Kit SDK, you must pass the `clientI
{: .note }
> Confirm that the Afterpay SDK is configured per the [instructions][configure-afterpay] before attempting to access `Afterpay.environment.payKitClientId`

You should use `CashAppPayFactory` to create an instance of the Cash App Pay Kit SDK. When doing so, you must specify the environment you will use, Sandbox or Production. The function `createSandbox()` will create an SDK instance in the Sandbox environment.

{: .info }
Expand All @@ -58,12 +57,14 @@ You should use `CashAppPayFactory` to create an instance of the Cash App Pay Kit
Creating a Sandbox Cash App Pay Kit SDK instance:

``` kotlin
val payKit : CashAppPay = CashAppPayFactory.createSandbox(Afterpay.environment.payKitClientId)
val cashAppPay : CashAppPay =
CashAppPayFactory.createSandbox(Afterpay.environment.payKitClientId)
```

Creating a Production Cash App Pay Kit SDK instance:
``` kotlin
val payKit : CashAppPay = CashAppPayFactory.create(Afterpay.environment.payKitClientId)
val cashAppPay : CashAppPay =
CashAppPayFactory.create(Afterpay.environment.payKitClientId)
```

{: .info }
Expand All @@ -82,18 +83,25 @@ interface CashAppPayListener {
You register with the SDK instance you’ve created above:

``` kotlin
payKit.registerForStateUpdates(this)
private val cashAppPayListener =
object : CashAppPayListener {
override fun cashAppPayStateDidChange(newState: CashAppPayState) {
// TODO
}
}

cashAppPay.registerForStateUpdates(cashAppPayListener)
```

You should also use the **Unregister** function when you're done with the SDK:

``` kotlin
payKit.unregisterFromStateUpdates()
cashAppPay.unregisterFromStateUpdates()
```

### States

`CashAppPayState` is a sealed class parameter. We suggest that you use a Kotlin `when` statement on it. Some of these possible states are for information only, but most drive the logic of your integration. The most critical states to handle are in the table below:
`CashAppPayState` is a sealed class. Some states are for information only, but most will drive the logic of your integration. The most critical states to handle are in the table below:

| State | Description |
|:-------|:------------|
Expand All @@ -104,27 +112,27 @@ payKit.unregisterFromStateUpdates()

## Step 4: Implement Deep Linking

The authorization flow will bring Cash App to the foreground on the Customer’s device. After the Customer either authorizes or declines, your app must be returned to the foreground, which means we need a way to call your app from Cash App. This is accomplished by [declaring an incoming intent][intent-filter]{:target="_blank"} filter on your app's Android Manifest and passing a corresponding redirect URI that uses the SDK when creating a customer request (as can be seen on the next step).

Here’s an example of how this integration looks for your `AndroidManifest`:
The authorization flow will bring Cash App to the foreground on the Customer’s device. After the Customer either authorizes or declines, the Cash App SDK will attempt to return your app to the foreground. This is accomplished by [declaring an intent filter][intent-filter]{:target="_blank"} on your app's Android Manifest. You then pass a corresponding redirect URI when launching Cash APP SDK, see next step.

``` xml
```xml
<!-- Intent filter to allow Cash App Pay SDK to redirect to your app.
Consider creating a custom scheme to ensure only your app is launched. -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data
android:host="example.com"
android:scheme="example" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<!-- Register the Cash App Pay Kit redirect URI or URL. Change this accordingly in your app. -->
<data
android:scheme="cashpaykit"
android:host="checkout" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
```

You can also use a [Verified App Link](https://developer.android.com/training/app-links/verify-android-applinks) and `https` scheme. However that is outside the scope of example.

## Step 5: Create a Customer Request

You can create a customer request as soon as you know the amount you’d like to charge or if you'd like to create an on-file payment request. You can create this request as soon as your **checkout view controller** loads, so that your customer can authorize the request without delay.
You can create a customer request as soon as you know the amount you’d like to charge or if you'd like to create an on-file payment request. You can create this request as soon as your checkout screen loads, so that your customer can authorize the request without delay.

### Step 5A: Sign the Order Token

Expand Down Expand Up @@ -159,11 +167,11 @@ To charge a one-time payment, your **Create Request** call might look like this
``` kotlin
val request = CashAppPayPaymentAction.OneTimeAction(
currency = CashAppPayCurrency.USD,
amount = (cashAppData.amount * 100).toInt(),
amount = TODO(), // the amount of the transaction
scopeId = cashAppData.merchantId,
)

payKit.createCustomerRequest(request, cashAppData.redirectUri)
cashAppPay.createCustomerRequest(request, cashAppData.redirectUri)
```

## Step 6: Authorize the Customer Request
Expand All @@ -173,7 +181,7 @@ payKit.createCustomerRequest(request, cashAppData.redirectUri)
Once the Cash App Pay Kit SDK is in the `ReadyToAuthorize` state, you can display the Cash App Pay button. When the customer taps the button, you can authorize the customer request. See [Cash Button Docs][cash-button-docs]{:target='_blank'} to learn more about the Cash App Pay button component.

``` kotlin
payKit.authorizeCustomerRequest()
cashAppPay.authorizeCustomerRequest()
```

{: .info }
Expand Down
Loading

0 comments on commit baafca6

Please sign in to comment.