Initiate In-App payment

Merchant applications can use APIs to fetch Payment information details with custom payment sheet.

The following functionalities are ready to perform a variety of payment operations:

  • Checking registered/enrolled card information
  • Creating a Transaction Request
  • Requesting payment with a custom payment sheet

Checking Registered/Enrolled Card Information

Before displaying the Samsung Pay button, a partner app can query card brand information for the user’s currently enrolled payment cards in Samsung Wallet to determine if payment is supported with the enrolled card.

To query the card brand, use the requestCardInfo() API method of the SamsungPaySdkFlutter class. The merchant app does not need to set a value for it now. However, before calling this method, CardInfoListener must be registered so its listener can provide onResult and onFailure events:

The following snippet shows how to retrieve the list of supported card brands from Samsung Wallet:

samsungPaySdkFlutterPlugin.requestCardInfo(cardInfoListener){onResult:(paymentCardInfo)

      showCardList(paymentCardInfo);
  
    }, onFailure:(errorCode, bundle){
  
      showError(errorCode, bundle);
  
    }
    ));

Creating a Transaction Request

Upon successful initialization of the SamsungPaySdkFlutter class, the merchant app needs to create a transaction request with payment information

Using the custom payment sheet

To initiate a payment transaction with Samsung Wallet’s custom payment sheet, your merchant app must populate the following mandatory fields in CustomSheetPaymentInfo:

  • Merchant Name - as it will appear in Samsung Wallet’s payment sheet, as well as the user's card account statement.
  • CustomSheet - is called when the user changes card on the custom payment sheet in Samsung Wallet.

Optionally, the following fields can be added to the payment information:

Merchant ID - can be used for the merchant’s own designated purpose at its discretion unless the merchant uses an indirect PG like Stripe or Braintree. If an indirect PG is used, this field must be set to the merchant’s Payment Gateway ID fetched from the Samsung Pay Developers portal.

Order Number - usually created by the merchant app via interaction with a PG. This number is required for refunds and chargebacks. In the case of Visa cards, the value is mandatory. The allowed characters are [A-Z][a-z][0-9,-] and the length of the value can be up to 36 characters.

Address - the user’s billing and/or shipping address.

Allowed Card Brands - specifies card brands accepted by the merchant. If no brand is specified, all brands are accepted by default. If at least one brand is specified, all other card brands not specified are set to "card not supported’ on the payment sheet.

Here’s the 'CustomSheetPaymentInfo' structure:

  String? merchantId;
  String merchantName;
  String? orderNumber;
  AddressInPaymentSheet? addressInPaymentSheet;
  List<Brand>? allowedCardBrand;
  PaymentCardInfo? cardInfo;
  bool? isCardHolderNameRequired;
  bool? isRecurring;
  String? merchantCountryCode;
  CustomSheet customSheet;
  Map<String,dynamic>? extraPaymentInfo;

Your merchant app sends this CustomSheetPaymentInfo to Samsung Wallet via the applicable Samsung Pay SDK Flutter Plugin API methods. Upon successful user authentication in direct mode, Samsung Wallet returns the above "Payment Info" structure and a result string. The result string is forwarded to the PG by your merchant app to complete the transaction. It will vary based on the PG you’re using.

The following example demonstrates how to populate customSheet in the CustomSheetPaymentInfo class.

    List<Brand> brandList = [];
    brandList.add(Brand.VISA);
    brandList.add(Brand.MASTERCARD);
    brandList.add(Brand.AMERICANEXPRESS);


    CustomSheetPaymentInfo customSheetPaymentInfo= CustomSheetPaymentInfo(merchantName:"merchantName", customSheet: customSheet);
    customSheetPaymentInfo.setMerchantId("123456");
    customSheetPaymentInfo.setMerchantName("Sample Merchant");
    customSheetPaymentInfo.setAddressInPaymentSheet(AddressInPaymentSheet.NEED_BILLING_SEND_SHIPPING);
    customSheetPaymentInfo.setCardHolderNameEnabled(true);
    customSheetPaymentInfo.setRecrringEnabled(false);
    customSheetPaymentInfo.setCustomSheet(customSheet);
    customSheetPaymentInfo.allowedCardBrand = brandList;
  return customSheetPaymentInfo;

Requesting Payment with a Custom Payment Sheet

The startInAppPayWithCustomSheet() method of the SamsungPaySdkFlutter class is applied to request payment using a custom payment sheet in Samsung Wallet. The two methods are defined as follows:

startInAppPayWithCustomSheet() - initiates the payment request with a custom payment sheet. The payment sheet persist for 5 minutes after the API is called. If the time limit expires, the transaction fails.

updateSheet() - updates the custom payment sheet if any values on the sheet are changed. As of API level 1.5, a merchant app can update the custom sheet with a custom error message. Refer to Updating sheet with custom error message.

When you call the startInAppPayWithCustomSheet() method, a custom payment sheet is displayed on the merchant app screen. From it, the user can select a registered card for payment and change the billing and shipping addresses, as necessary.

The result is delivered to CustomSheetTransactionInfoListener, which provides the following events:

onSuccess() - called when Samsung Wallet confirms payment. It provides the CustomSheetPaymentInfo object and the paymentCredential JSON string.

CustomSheetPaymentInfo is used for the current transaction. It contains amount, shippingAddress, merchantId, merchantName, orderNumber. API methods exclusively available in the onSuccess() callback comprise:

  • getPaymentCardLast4DPAN() – returns the last 4 digits of the user's digitized personal/primary identification number (DPAN)

  • getPaymentCardLast4FPAN() – returns the last 4 digits of the user's funding personal/primary identification number (FPAN)

  • getPaymentCardBrand() – returns the brand of the card used for the transaction

  • getPaymentCurrencyCode() – returns the ISO currency code in which the transaction is valued

  • getPaymentShippingAddress() – returns the shipping/delivery address for the transaction

  • getPaymentShippingMethod() – returns the shipping method for the transaction.

For PGs using the direct model (network tokens), the paymentCredential is a JSON object containing encrypted cryptogram which can be passed to the PG. PGs using the indirect model (gateway tokens) like Stripe, it is a JSON object containing reference (card reference – a token ID generated by the PG) and status (i.e., AUTHORIZED, PENDING, CHARGED, or REFUNDED). Refer to Payment credential sample for details.

onCardInfoUpdated() - called when the user changes the payment card. In this callback, updateSheet() method must be called to update current payment sheet.

onFailure() - called when the transaction fails, returns the error code and errorData bundle for the failure

Here’s how to call the startInAppPayWithCustomSheet() method of the SamsungPaySdkFlutter class:

class CustomSheetTransactionInfoListener{
  Function(PaymentCardInfo paymentCardInfo, CustomSheet customSheet) onCardInfoUpdated;
  Function(CustomSheetPaymentInfo customSheetPaymentInfo, String paymentCredential,  Map<String, dynamic>? extraPaymentData) onSuccess;
  Function(String errorCode, Map<String, dynamic> bundle) onFail;
  CustomSheetTransactionInfoListener({required this.onCardInfoUpdated, required this.onSuccess, required this.onFail});
}

void onCardInfoUpdated(CardInfo selectedCardInfo, CustomSheet customSheet) {
    AmountBoxControl amountBoxControl =
        customSheet.getSheetControl(AMOUNT_CONTROL_ID) as AmountBoxControl;
    amountBoxControl.updateValue(PRODUCT_ITEM_ID, 1000);
    amountBoxControl.updateValue(PRODUCT_TAX_ID, 50);
    amountBoxControl.updateValue(PRODUCT_SHIPPING_ID, 10);
    amountBoxControl.updateValue(PRODUCT_FUEL_ID, 0, "Pending");
    amountBoxControl.setAmountTotal(1060, AmountConstants.FORMAT_TOTAL_PRICE_ONLY);
    customSheet.updateControl(amountBoxControl);
  }
}

void startInAppPayWithCustomSheet(CustomSheetPaymentInfo customSheetPaymentInfo,CustomSheetTransactionInfoListener? customSheetTransactionInfoListener){
    try{
      methodChannelSamsungPaySdkFlutter?.startInAppPayWithCustomSheet(customSheetPaymentInfo, customSheetTransactionInfoListener);
    }on PlatformException catch(e){
      print(e);
    }
  }
override fun onSuccess(response: CustomSheetPaymentInfo, paymentCredential: String, extraPaymentData: Bundle){}
 override fun onFailure(errorCode: Int, errorData: Bundle?){}