> ## Documentation Index
> Fetch the complete documentation index at: https://docs.anglpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Stripe - Affirm

> Configure Affirm via Stripe as a payment method in Gr4vy.

Affirm is a buy now, pay later option that lets eligible buyers split purchases into installments.

## Setup

Follow the [Stripe setup instructions](./stripe) before configuring Affirm.

After setting up your Stripe account, make sure Affirm is enabled as a payment method in Stripe.

For shared APM credentials and payment IDs, see [Stripe APM credentials](./stripe#apm-credentials).

## Features

Stripe Affirm payments support the following features:

* **Partial capture** - Capture a portion of the authorized amount
* **Refunds** - Refund transactions in full or in part
* **Partial refunds** - Issue multiple partial refunds up to the captured amount
* **Zero auth** - Verify a payment method without capturing funds
* **Webhook integration** - Receive asynchronous payment updates
* **Redirect checkout** - Redirect buyers to approve the payment

## Supported countries

Stripe supports transactions from buyers in `CA` and `US`.

## Supported currencies

Stripe supports processing payments in `CAD` and `USD`.

## Limitations

The following features are not supported by this connector:

* **Delayed capture** - Authorization and capture must happen together
* **Over-capture** - Capturing more than the authorized amount is not supported
* **Void** - Canceling an authorization is not available
* **Payment method tokenization** - Storing payment methods for recurring transactions is not supported
* **Transaction sync** - Automated status synchronization is not available
* **Settlement reporting** - Settlement reporting is not available
* **Deep linking** - Direct app linking is not supported
* **Partial authorization** - Authorizing only a portion of the requested amount is not supported

## Webhooks

Affirm payments and refunds can be completed asynchronously, so webhooks must be configured to update the status of transactions. Webhooks are configured in the Stripe Dashboard within Developer Settings under **Webhooks**.

The Affirm connector relies on the following Stripe webhooks:

* `charge.expired`
* `charge.refund.updated`
* `charge.refunded`
* `payment_intent.succeeded`
* `payment_intent.amount_capturable_updated`
* `payment_intent.payment_failed`
* `payment_intent.partially_funded`
* `payment_intent.canceled`
* `checkout.session.async_payment_succeeded`

## Integration

The default integration for Affirm via Stripe uses a redirect to a payments page hosted by Gr4vy.

### Redirect integration

Start by creating a new transaction with the following required fields.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
  	transactionCreate: new TransactionCreate()
  	{
  		Amount = 1299,
  		Currency = "USD",
  		Country = "US",
  		PaymentMethod =
  			TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
  				new RedirectPaymentMethodCreate()
  				{
  					Method = "affirm",
  					Country = "US",
  					Currency = "USD",
  					RedirectUrl = "https://example.com/callback",
  				}
  			),
  	}
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  currency := "USD"
  country := "US"
  method := components.RedirectPaymentMethodCreateMethodAffirm
  redirectUrl := "https://example.com/callback"

  redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
  	Method: method,
  	Country: country,
  	Currency: currency,
  	RedirectURL: redirectUrl,
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
  	Amount:        amount,
  	Currency:      currency,
  	Country:       &country,
  	PaymentMethod: &paymentMethod,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
  	.transactionCreate(TransactionCreate.builder()
  		.amount(1299L)
  		.currency("USD")
  		.country("US")
  		.paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
  			.method(RedirectPaymentMethodCreateMethod.AFFIRM)
  			.country("US")
  			.currency("USD")
  			.redirectUrl("https://example.com/callback")
  			.build()))
  		.build())
  	.call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
  	amount: 1299,
  	currency: 'USD',
  	country: 'US',
  	paymentMethod: new RedirectPaymentMethodCreate(
  		method: 'affirm',
  		country: 'US',
  		currency: 'USD',
  		redirectUrl: 'https://example.com/callback'
  	)
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
  	amount=1299,
  	currency="USD",
  	country="US",
  	payment_method={
  		"method": "affirm",
  		"country": "US",
  		"currency": "USD",
  		"redirect_url": "https://example.com/callback",
  	}
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
  	amount: 1299,
  	currency: "USD",
  	country: "US",
  	paymentMethod: {
  		method: "affirm",
  		country: "US",
  		currency: "USD",
  		redirectUrl: "https://example.com/callback"
  	}
  })
  ```
</CodeGroup>

After the transaction is created, the API response includes a `payment_method.approval_url` and the status is set to `buyer_approval_pending`.

```json theme={"system"}
{
	"type": "transaction",
	"id": "ea1efdd0-20f9-44d9-9b0b-0a3d71e9b625",
	"payment_method": {
		"type": "payment-method",
		"approval_url": "https://cdn.gr4vy.com/connectors/..."
	},
	"method": "affirm"
}
```

Redirect the buyer to the `approval_url` (open in a browser or Webview), where they can complete the payment. Once the buyer completes the payment, the transaction progresses to an `authorization_succeeded` or `capture_succeeded` state.

### Direct integration

If you intend to use your own hosted page, you can include an `integration_client` parameter set to `web`, `ios` or `android` when creating a new transaction.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
  	transactionCreate: new TransactionCreate()
  	{
  		Amount = 1299,
  		Currency = "USD",
  		Country = "US",
  		IntegrationClient = "ios",
  		PaymentMethod =
  			TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
  				new RedirectPaymentMethodCreate()
  				{
  					Method = "affirm",
  					Country = "US",
  					Currency = "USD",
  					RedirectUrl = "myapp://callback",
  				}
  			),
  	}
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  currency := "USD"
  country := "US"
  integrationClient := "ios"
  method := components.RedirectPaymentMethodCreateMethodAffirm
  redirectUrl := "myapp://callback"

  redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
  	Method: method,
  	Country: country,
  	Currency: currency,
  	RedirectURL: redirectUrl,
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
  	Amount:            amount,
  	Currency:          currency,
  	Country:           &country,
  	IntegrationClient: &integrationClient,
  	PaymentMethod:     &paymentMethod,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
  	.transactionCreate(TransactionCreate.builder()
  		.amount(1299L)
  		.currency("USD")
  		.country("US")
  		.integrationClient("ios")
  		.paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
  			.method(RedirectPaymentMethodCreateMethod.AFFIRM)
  			.country("US")
  			.currency("USD")
  			.redirectUrl("myapp://callback")
  			.build()))
  		.build())
  	.call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
  	amount: 1299,
  	currency: 'USD',
  	country: 'US',
  	integrationClient: 'ios',
  	paymentMethod: new RedirectPaymentMethodCreate(
  		method: 'affirm',
  		country: 'US',
  		currency: 'USD',
  		redirectUrl: 'myapp://callback'
  	)
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
  	amount=1299,
  	currency="USD",
  	country="US",
  	integration_client="ios",
  	payment_method={
  		"method": "affirm",
  		"country": "US",
  		"currency": "USD",
  		"redirect_url": "myapp://callback",
  	}
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
  	amount: 1299,
  	currency: "USD",
  	country: "US",
  	integrationClient: "ios",
  	paymentMethod: {
  		method: "affirm",
  		country: "US",
  		currency: "USD",
  		redirectUrl: "myapp://callback"
  	}
  })
  ```
</CodeGroup>

After the transaction is created, the API response includes a `session_token`. You use this token with the [session endpoint](/reference/transactions/get-transaction-session) to retrieve the session data for the transaction and build a custom page.

```json theme={"system"}
POST /transactions/:transaction_id/session?token=:session_token

{
  "session_data": {
    "publishableKey": "some_key",
    "clientSecret": "client_secret",
    "returnUrl": "url_to_return_after_payment_completed"
  },
  "default_completion_url": "https://example.com/callback",
  "integration_client": "ios"
}
```

#### Mobile redirect integration completion

On mobile integrations you should send a GET request to the `default_completion_url` provided in the session response.

## Payment IDs

When creating the transaction, the `payment_service_transaction_id` is the client secret, and in the `extra_xids` field you can find the payment intent ID as `payment_id`.

After the transaction is approved by the user, the `payment_service_transaction_id` is updated to the payment intent ID.
