---
schema_version: "1"
id: e0cebbe92beca7a9e23d649831f1ab92bd9d2d82c8ecf7ef1d282d9a81829cb6
title: Create Saved Payment Method Asynchronously
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/commerce-cloud/salesforce-commerce/guides/d2c-commerce/b2b-comm-spm-client-side-create-async.md
canonical_url: https://developer.salesforce.com/docs/commerce/salesforce-commerce/guide/b2b-comm-spm-client-side-create-async.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 21295e4c46a9fb9161801b1e53e5335b468b33be2895ba06bea6da05259395f1
products:
  - B2B Commerce Developer Guide
  - Salesforce APIs
---
# Create Saved Payment Method Asynchronously

Use the asynchronous flow when payment gateways generate tokens asynchronously. You create the SPM record with a Pending status, and the token is updated later via a webhook notification.

Here’s the high-level workflow for creating a saved payment method record asynchronously.

![High-level workflow diagram for creating a saved payment method record asynchronously using a third-party payment gateway](https://developer.salesforce.com/media/d2c-commerce/async_spm_creation.png '{"class": "image-lg", "title": "Asynchronously Saved Payment Method Creation"}')

Here are the steps to create a saved payment method asynchronously using the tokenized payment details received from a third-party payment gateway:

1. The client builds the asynchronous gateway adapater. See [Building a Asynchronous Gateway Adapter](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_commercepayments_async_adapter_concept.htm).
2. The client configures a webhook endpoint to receive notifications from the payment gateway. This webhook endpoint is mapped to Salesforce Notify API through an Apex adapter to receive notifications from payment gateway about payment events.
3. The client calls the payment gateway with the payment details entered through the buyer component.
4. The gateway returns a reference number that’s later used to correlate the asynchronous update.
5. The client-side component creates the saved payment method record using the SavedPaymentMethod sObject API. It sets all required fields, including:

   - `status` = `Pending`
   - `gatewayToken` = empty
   - `asyncGatewayRefNumber` (mandatory for async flows)

   **Sample JSON request**

   ```json
   {
     "merchantAccountId": "8zbSM0000000F8jYAE",
     "referenceOwnerId": "001SM00000FwMhEYAV",
     "paymentGatewayId": "0b0SM0000002oLhYAI",
     "Status": "Pending",
     "usageType": "OFFSESSION",
     "Name": "AmazonPay...001",
     "GatewayReference": "cus_TEGn3J3WI5onpb",
     "type": "extd_wallet",
     "Checksum": "UNIQUE_GATEWAY_HASH_Wallet_10001",
     "ExtendedPaymentMethodType": "amazon_pay",
     "last4": "1234"
   }
   ```

   **Sample JSON response**

   ```json
   {
     "id": "12qSM000000qfS6YAI",
     "success": true,
     "errors": []
   }
   ```

6. When the token is generated, the gateway sends a webhook to the configured endpoint with the same `AsyncGatewayRefNumber`. Upon receiving this notification, the SPM record status is updated to Active, and the gateway token is stored in the SavedPaymentMethod object.

**Salesforce Commerce Payments Notify API for Stripe**

Resource: `/commerce/payments/notify/stripe`

Here’s a sample Stripe notify response:

```json
{
  "id": "evt_1LgJRtSGZlJjI7oJelLGgSCg",
  "object": "event",
  "api_version": "2020-03-02",
  "created": 1662776977,
  "data": {
    "object": {
      "id": "acct_1M6wYxIDXrazRzyT",
      "object": "account",
      "business_profile": {
        "mcc": "5691",
        "name": null,
        "support_address": null,
        "support_email": null,
        "support_phone": "+917331163878",
        "support_url": null,
        "url": "https://www.salesforce.com"
      },
      "capabilities": {
        "card_payments": "inactive",
        "transfers": "active"
      },
      "charges_enabled": true,
      "controller": {
        "type": "application"
      },
      "country": "IN",
      "default_currency": "inr",
      "details_submitted": true,
      "email": "harish.lnmiit@gmail.com",
      "payouts_enabled": true,
      "settings": {
        "bacs_debit_payments": {},
        "branding": {
          "icon": null,
          "logo": null,
          "primary_color": null,
          "secondary_color": null
        },
        "card_issuing": {
          "tos_acceptance": {
            "date": null,
            "ip": null
          }
        },
        "card_payments": {
          "statement_descriptor_prefix": "KIAA",
          "statement_descriptor_prefix_kanji": null,
          "statement_descriptor_prefix_kana": null
        },
        "dashboard": {
          "display_name": "INAccount1",
          "timezone": "Etc/UTC"
        },
        "payments": {
          "statement_descriptor": "KIAAN",
          "statement_descriptor_kana": null,
          "statement_descriptor_kanji": null
        },
        "sepa_debit_payments": {}
      },
      "type": "standard"
    },
    "previous_attributes": {}
  },
  "livemode": true,
  "pending_webhooks": 1,
  "request": {
    "id": null,
    "idempotency_key": null
  },
  "type": "account.updated"
}
```

Here’s a sample Adyen async response:

```json
{
  "live": "false",
  "notificationItems": [
    {
      "NotificationRequestItem": {
        "eventCode": "RECURRING_CONTRACT",
        "success": "true",
        "merchantReference": "KLARNA_TOKENIZE_TEST_EUR",
        "pspReference": "Q26N98PBKQ7F42W5",
        "paymentMethod": "klarna",
        "merchantAccountCode": "Amazon879ECOM",
        "originalReference": "KB44M8CFZRRPDKV5",
        "amount": {
          "currency": "EUR",
          "value": 100
        },
        "additionalData": {
          "recurring.shopperReference": "UNIQUE_SHOPPER_ID_12345",
          "recurring.recurringDetailReference": "Q26N98PBKQ7F42W5"
        }
      }
    }
  ]
}
```

Here’s a sample user interface that shows the status of a Saved Payment Method record before and after the webhook endpoint notification is sent.

Before webhook:

![Saved Payment Method record showing Pending status before the webhook notification is received from the payment gateway](https://developer.salesforce.com/media/d2c-commerce/spm_before_webhook.png '{"class": "image-lg", "title": "Saved Payment Method Status Before Webhook"}')

After webhook:

![Saved Payment Method record showing Active status and stored gateway token after the webhook notification is received](https://developer.salesforce.com/media/d2c-commerce/spm_after_webhook.png '{"class": "image-lg", "title": "Saved Payment Method Status After Webhook"}')

**See Also**

- [_Object Reference for the Salesforce Platform_: SavedPaymentMethod](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_savedpaymentmethod.htm)
- [_REST API Developer Guide_: Create a Record](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_create.htm)
- [_Apex Developer Guide_: Set Up a Asynchronous Payment Gateway Adapter](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_commercepayments_async_adapter_setup.htm)
- [_Apex Developer Guide_: Builder Examples for Payment Gateway Adapters](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_commercepayments_builder_examples.htm)
