---
schema_version: "1"
id: c69249f537cf7456a085f323d8278ab41de80158bbd591570d3ebf1afd8f13a6
title: Use Saved Payment Method in Sale Transactions
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-apex-sale-transaction.md
canonical_url: https://developer.salesforce.com/docs/commerce/salesforce-commerce/guide/b2b-comm-spm-client-side-apex-sale-transaction.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 46efe28a6259dc066b8084a5e75e5f53d117a31e35b42113e1dbeea318d71dd9
products:
  - B2B Commerce Developer Guide
  - Salesforce APIs
---
# Use Saved Payment Method in Sale Transactions

After you create a Saved Payment Method (SPM), you can use it for Sale transactions by implementing the sale request processing in a class that implements `commercepayments.PaymentGatewayAdapter`.

If the SPM record is created with a `Type` value of `ExtendedAPM` or `ExtendedWallet` and includes an `ExtendedPaymentMethodType`, you can access these fields in the Sale request with the Apex layer using a query like the following:

```apex
private static SavedPaymentMethod fetchSavedPaymentMethod(Id idToProcess) {
    QueryUtils q = new QueryUtils(SavedPaymentMethod.SObjectType);
    q.getSelectClause().addField('GatewayToken', false);
    q.getSelectClause().addField('GatewayReference', false);
    q.getSelectClause().addField('ExtendedPaymentMethodType', false);
    q.getSelectClause().addField('type', false);
    q.setWhereClause(' WHERE Id = \'' + idToProcess + '\'');
    return (SavedPaymentMethod) Database.query(q.buildSOQL())[0];
}

//Sample Adyen sale transaction request.
private String buildSaleRequest(commercepayments.SaleRequest saleRequest) {
    String currencyIso = saleRequest.currencyIsoCode;
    commercepayments.SaleApiPaymentMethodRequest paymentMethod = saleRequest.paymentMethod;
    if (currencyIso == null) {
        currencyIso = UserInfo.getDefaultCurrency();
    }
    JSONGenerator jsonGeneratorInstance = JSON.createGenerator(true);
    jsonGeneratorInstance.writeStartObject();
    jsonGeneratorInstance.writeStringField('merchantAccount', '{!$Credential.Username}');
    jsonGeneratorInstance.writeStringField('reference', String.valueOf(Datetime.now().getTime()) + String.valueOf(Math.random()).substring(2, 8));

    jsonGeneratorInstance.writeFieldName('amount');
    jsonGeneratorInstance.writeStartObject();
    jsonGeneratorInstance.writeStringField('value', String.ValueOf((saleRequest.amount * 100.0).intValue()));
    jsonGeneratorInstance.writeStringField('currency', currencyIso);
    jsonGeneratorInstance.writeEndObject();

    jsonGeneratorInstance.writeFieldName('paymentMethod');
    jsonGeneratorInstance.writeStartObject();
    String shopperReference;
    String token;
    String type = 'scheme';
    Id idToProcess = saleRequest.paymentMethod.id;
    Map < String, String > paymentTypeMap = new Map < String, String > {
        'us_bank_account' => 'ach',
        'sepa_debit' => 'sepadirectdebit',
        'au_becs_debit' => 'directdebit_AU',
        'bacs_debit' => 'directdebit_GB',
        'amazon_pay' => 'amazonpay',
        'googlepay' => 'paywithgoogle'
    };
    if (idToProcess.getSObjectType() == SavedPaymentMethod.SObjectType) {
        SavedPaymentMethod savedPaymentMethod = fetchSavedPaymentMethod(idToProcess);
        token = savedPaymentMethod.GatewayToken;
        shopperReference = savedPaymentMethod.GatewayReference;
        String paymentMethodType = savedPaymentMethod.type;
        String extendedPaymentMethodType = savedPaymentMethod.ExtendedPaymentMethodType;
        System.debug('Queried SPM record for QA override');
        type = determinePaymentType(paymentMethodType, extendedPaymentMethodType, paymentTypeMap);
    }
    // Common JSON field population
    jsonGeneratorInstance.writeStringField('type', type);
    jsonGeneratorInstance.writeStringField('storedPaymentMethodId', token);
    jsonGeneratorInstance.writeEndObject();
    jsonGeneratorInstance.writeStringField('shopperInteraction', 'ContAuth');
    jsonGeneratorInstance.writeStringField('recurringProcessingModel', 'UnscheduledCardOnFile');
    jsonGeneratorInstance.writeStringField('shopperReference', shopperReference);
    //jsonGeneratorInstance.writeStringField('holderName', 'John Smith');
    jsonGeneratorInstance.writeNumberField('captureDelayHours', 0);
    jsonGeneratorInstance.writeEndObject();
    return jsonGeneratorInstance.getAsString();
}
```

**See Also**

- [_Apex Reference Guide_: PaymentGatewayAdapter Interface](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_interface_commercepayments_PaymentGatewayAdapter.htm)
- [_Apex Reference Guide_: CommercePayments Namespace](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_namespace_commercepayments.htm)
