Samsung Pay Web Checkout enables seamless, secure payments on your website using cards stored in the Samsung Wallet app. This JavaScript-based SDK makes it easy to integrate Samsung Pay into your desktop or mobile web checkout experience.
Key Features
Cross-Device Support Users can complete purchases on both desktop and mobile browsers.
Samsung Wallet Integration Payments are authorized using cards saved in the Samsung Wallet mobile app.
Secure Credential Transmission Payment credentials are securely generated on the mobile device and transmitted to your website.
Multiple Authentication Options Users can bind their device by either:
Entering their Samsung account email, or
Scanning a QR code displayed on your checkout page.
User scenario with the service flow
The following figures describe the user scenario for making a purchase through Samsung Pay Web Checkout.
The following figure illustrates the Samsung Pay Web Checkout flow.
Payment Initiation & Device Binding
The user selects Samsung Pay as the payment method at checkout.
A Web Checkout UI launches, prompting the user to link their device:
Enter Samsung account email, or
Scan a QR code using their mobile device.
A push notification is sent to their Samsung Wallet app.
For mobile devices:
The user selects Samsung Pay as the payment method at checkout.
A payment request pop-up is displayed and prompts the user to select the “Pay” button. The Samsung Wallet app automatically opens on the current device.
User confirmation on mobile device
The user taps the notification on their device.
The Samsung Wallet app opens a payment sheet showing order details.
The user selects a payment card and authorizes the purchase.
Payment completion
A "Verified" screen is shown in the browser as the transaction is confirmed.
Your website receives a secure payment credential from Samsung Pay.
You forward this credential to your payment processor to complete the purchase.
3.3.2 Web Checkout Integration
Samsung Pay Web Checkout enables seamless online payments using Samsung Wallet on supported mobile devices. Let’s us look how to integrate the Web Checkout SDK into your website and process secure, tokenized transactions.
Prerequisites
Before integrating Samsung Pay Web Checkout, ensure the following:
Samsung Pay Merchant ID: You must complete the partner onboarding process to obtain a valid Merchant ID.
Tokenization Support: Your acquirer and issuer must support tokenized in-app transactions per card network standards.
Web Checkout Integration Steps
To integrate the Samsung Pay Web Checkout solution to your website:
"STAGE_WITHOUT_APK" – Testing without device (simulated)
"PRODUCTION" – Live environment
const samsungPayClient = new SamsungPay.PaymentClient({environment: "STAGE"});
Note:If your project has a Content-Security-Policy (CSP) applied, please ensure that you add a nonce to the CSS to maintain compliance. This can be done by updating your SDK configuration as follows:
const samsungPayClient = new SamsungPay.PaymentClient({environment: "STAGE", nonce: "your-nonce"});
Check Availability
Verify Samsung Pay availability in the user’s browser/device:
samsungPayClient.isReadyToPay(paymentMethods).then(function(response) {
if (response.result) {
// add a payment button
}
}).catch(function(err) {
console.error(err);
});
Add Samsung Pay Button
Use the official Samsung Pay button asset and adhere to branding guidelines:
<div id="samsungpay-container">
<button id="samsung-pay-btn">
<img src="/your/path../samsung-pay-button.png" alt="Samsung Pay" style="{follow the Samsung's official branding guideline}" />
</button>
</div>
Note:Download the official Samsung Pay button image and branding guideline from Download page and use it directly in your HTML as shown here. Download.
Trigger the Web Checkout interface when the user clicks the payment button. When the onClick() event is triggered, your event handler must call the loadPaymentSheet() method, which initiates the Web Checkout UI flow. When the user confirms the payment from their mobile device, you receive the paymentCredential object generated by the device.
Note:Extract the payment credential information from the 3DS.Data key within the paymentCredential object and process it through your payment provider. Inform the Samsung server of the payment result using the notify() method within the paymentResult object.
Note:For information about the content of the PaymentMethods, TransactionDetail, and PaymentCredential data structures, see the API Reference.
3.3.3 Decrypting Payment Credentials
For security, Samsung Pay encrypts the payment credential using JSON Web Encryption (JWE). You must decrypt this payload to extract the payment token and process the transaction.
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class DeveloperPortalSample {
public static void main(String[] args) throws Exception {
// Example JWE string (replace with your actual JWE and private key path)
String encryptedText = {{encryptedPayload}};
String privateKeyPath = "./rsapriv.der";
String PRIVATE_KEY = Base64.getEncoder().encodeToString(Files.readAllBytes(Paths.get(privateKeyPath)));
String result = decryptJWE(encryptedText, PRIVATE_KEY);
System.out.println(result);
}
public static String decryptJWE(String encryptedText, String privateKeyText) throws Exception {
// Split JWE parts by '.'
String delims = "[.]";
String[] tokens = encryptedText.split(delims);
if (tokens.length < 5) {
throw new IllegalArgumentException("Invalid JWE format");
}
// Decode and parse JWE header
byte[] headerBytes = Base64.getUrlDecoder().decode(tokens[0]);
String headerJson = new String(headerBytes);
ObjectMapper mapper = new ObjectMapper();
JsonNode header = mapper.readTree(headerJson);
// Extract algorithm information from header
String alg = header.has("alg") ? header.get("alg").asText() : "RSA1_5";
String enc = header.has("enc") ? header.get("enc").asText() : "A128GCM";
// Convert private key
byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyText);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);
// Decode encrypted key, IV, ciphertext, and authentication tag
byte[] encKey = Base64.getUrlDecoder().decode(tokens[1]);
byte[] iv = Base64.getUrlDecoder().decode(tokens[2]);
byte[] cipherText = Base64.getUrlDecoder().decode(tokens[3]);
byte[] tag = Base64.getUrlDecoder().decode(tokens[4]);
// Create Cipher instance based on key management algorithm
String keyManagementAlgorithm;
boolean useAAD = false;
if ("RSA-OAEP".equals(alg)) {
keyManagementAlgorithm = "RSA/ECB/OAEPPadding";
// At Samsung, OAEP uses AAD (Additional Authenticated Data)
useAAD = true;
} else if ("RSA1_5".equals(alg)) {
keyManagementAlgorithm = "RSA/ECB/PKCS1Padding";
// while RSA1_5 does not use AAD.
useAAD = false;
} else {
throw new IllegalArgumentException("Unsupported key management algorithm: " + alg);
}
// Decrypt the CEK (Content Encryption Key)
Cipher decryptCipher = Cipher.getInstance(keyManagementAlgorithm);
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] plainEncKey = decryptCipher.doFinal(encKey);
// Create Cipher instance based on content encryption algorithm
String contentEncryptionAlgorithm;
int gcmTagLength;
if ("A128GCM".equals(enc) || "A256GCM".equals(enc)) {
contentEncryptionAlgorithm = "AES/GCM/NoPadding";
gcmTagLength = 128;
} else {
throw new IllegalArgumentException("Unsupported content encryption algorithm: " + enc);
}
// Decrypt the content
Cipher contentCipher = Cipher.getInstance(contentEncryptionAlgorithm);
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(gcmTagLength, iv);
SecretKeySpec keySpec = new SecretKeySpec(plainEncKey, "AES");
contentCipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
// AAD handling: Use Base64Url-encoded header bytes as AAD
if (useAAD) {
byte[] encodedHeader = Base64.getUrlEncoder().withoutPadding().encode(headerBytes);
contentCipher.updateAAD(encodedHeader);
}
// Concatenate cipherText and tag, then pass to doFinal
byte[] cipherData = new byte[cipherText.length + tag.length];
System.arraycopy(cipherText, 0, cipherData, 0, cipherText.length);
System.arraycopy(tag, 0, cipherData, cipherText.length, tag.length);
byte[] plainText = contentCipher.doFinal(cipherData);
return new String(plainText, java.nio.charset.StandardCharsets.UTF_8);
}
Sample implementation in C#
using System;
using System.IO;
using System.Text;
using System.Text.Json.Nodes;
using System.Security.Cryptography;
public static void Main(string[] args)
{
// Example JWE string (replace with your actual JWE and private key path)
string encryptedText = {{encryptedPayload}};
string privateKeyPath = ./rsapriv.der";
// Read the private key file (DER format)
byte[] privateKeyBytes = File.ReadAllBytes(privateKeyPath);
// Decrypt the JWE
string result = decryptJWE(encryptedText, privateKeyBytes);
// Print the result
Console.WriteLine(result);
}
public static string decryptJWE(string encryptedText, byte[] privateKeyBytes)
{
// Split JWE parts by '.'
var parts = encryptedText.Split('.');
if (parts.Length < 5)
throw new ArgumentException("Invalid JWE format");
// Decode and parse JWE header
var headerBytes = Base64UrlDecode(parts[0]);
var headerJson = Encoding.UTF8.GetString(headerBytes);
var header = JsonNode.Parse(headerJson);
// Extract algorithm information from header
string alg = header?["alg"]?.ToString() ?? "RSA1_5";
string enc = header?["enc"]?.ToString() ?? "A128GCM";
// Convert private key (assume PKCS8 DER)
using var rsa = RSA.Create();
rsa.ImportPkcs8PrivateKey(privateKeyBytes, out _);
// Decode encrypted key, IV, ciphertext, and authentication tag
var encKey = Base64UrlDecode(parts[1]);
var iv = Base64UrlDecode(parts[2]);
var cipherText = Base64UrlDecode(parts[3]);
var tag = Base64UrlDecode(parts[4]);
// Create Cipher instance based on key management algorithm
bool useAAD = false;
if (alg == "RSA-OAEP")
{
// At Samsung, OAEP uses AAD (Additional Authenticated Data)
useAAD = true;
}
else if (alg == "RSA1_5")
{
// while RSA1_5 does not use AAD.
useAAD = false;
}
else
{
throw new ArgumentException($"Unsupported key management algorithm: {alg}");
}
// Decrypt the CEK (Content Encryption Key)
byte[] plainEncKey = alg == "RSA-OAEP"
? rsa.Decrypt(encKey, RSAEncryptionPadding.OaepSHA1)
: rsa.Decrypt(encKey, RSAEncryptionPadding.Pkcs1);
// Decrypt the content
using var aes = new AesGcm(plainEncKey, 16);
var plainText = new byte[cipherText.Length];
if (useAAD)
{
// AAD handling: Use Base64Url-encoded header bytes as AAD
var encodedHeader = Encoding.ASCII.GetBytes(Base64UrlEncode(headerBytes));
aes.Decrypt(iv, cipherText, tag, plainText, encodedHeader);
}
else
{
aes.Decrypt(iv, cipherText, tag, plainText);
}
return Encoding.UTF8.GetString(plainText).TrimEnd('\0');
}
private static byte[] Base64UrlDecode(string input)
{
string s = input.Replace('-', '+').Replace('_', '/');
switch (s.Length % 4)
{
case 2: s += "=="; break;
case 3: s += "="; break;
}
return Convert.FromBase64String(s);
}
private static string Base64UrlEncode(byte[] input)
{
return Convert.ToBase64String(input)
.TrimEnd('=')
.Replace('+', '-')
.Replace('/', '_');
}
3.3.4 Integration on WebView
Configure WebView enablements
To invoke Samsung Pay application in WebView, you should override the shouldOverrideUrlLoading method.
Javascript and DOM Storage are disabled in a WebView by default. You can enable through the WebSettings attached to your WebView.
WebSettings allows any website to use JavaScript and DOM Storage. For more information, visit WebSettings.
Sample code (Kotlin)
import android.webkit.webView
import android.webkit.webViewClient
import android.content.Intent
import android.content.ActivityNotFoundException
companion object {
private const val SAMSUNG_PAY_URL_PREFIX: String = "samsungpay"
private const val SAMSUNG_APP_STORE_URL: String = "samsungapps://ProductDetail/com.samsung.android.spay"
}
private lateinit var webView: WebView
webView.settings.run {
javaScriptEnabled = true
domStorageEnabled = true
}
webView.webViewClient = object: WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView,
request: WebResourceRequest
): Boolean {
// get URL from WebResourceRequest
val url = request.url.toString()
// add below if statement to check if URL is Samsung Pay or Samsung App Store deep link
if (url.startsWith(SAMSUNG_PAY_URL_PREFIX) || url.startsWith(SAMSUNG_APP_STORE_URL), ignoreCase = false) {
try {
val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
startActivity(intent)
} catch (e: ActivityNotFoundException) {
// Exception would be occured if the Samsung Wallet app is not installed.
// go to install Samsung Wallet app from market
val installIntent = Intent.parseUri("samsungapps://ProductDetail/com.samsung.android.spay", Intent.URI_INTENT_SCHEME)
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(installIntent)
}
// return true will cause that the URL will not be loaded in WebView
return true
}
// the remaining part of the shouldOverrideUrlLoading method code
// return false when you want to load URL automatically by WebView
return false
}
}
3.3.5 Sample Implementation
The following sample code implements the Samsung Pay Web Checkout button on a merchant site. The implementation steps are described in Web Checkout Integration.
For information about the content of the PaymentMethods, TransactionDetail, and PaymentCredential data structures, see the API Reference.
The PaymentMethods object defines the payment methods that the merchant supports.
"PaymentMethods" data structure elements
Key
Type
Required
Description
version
String
Required
Samsung Pay API version The supported value is 2.
serviceId
String
Required
Merchant ID that is assigned after onboarding
protocol
String
Required
Payment protocol type The supported value is PROTOCOL_3DS.
allowedBrands
List<String>
Required
List of supported card brands The possible values are:
visa
mastercard
amex
discover
elo
mada
cb
jaywan(TBD)
isRecurring
boolean
Optional
Value if payment is recurring The default value is false.
isBillingAddressRequired
boolean
Optional
Value if billing address must be included in the payment credentials. The default value is false.
isCardholderNameRequired
boolean
Optional
Value if cardholder name must be included in the payment credentials. The default value is false.
isCpfCardRequired
boolean
Optional
Value if CPF must be included in the payment credentials. The default value is false.
merchantChoiceBrands
Object
Optional
Data structure containing configuration information for a co-badged card.
merchantChoiceBrands.type
String
Required
Co-badged card display option for the payment sheet The possible values are:
MANDATORY = Only the brand defined in merchantChoiceBrands.brands is enabled
PREFERENCE = The brand defined in merchantChoiceBrands.brands is selected by default but the user can change it
merchantChoiceBrands.brands
List<String>
Required
List of supported brands for the co-badged card The possible values are:
mada
cb
extraPaymentInfo
Object
Optional
Data structure containing additional supported features
extraPaymentInfo.id
String
Required
Feature ID for the additional feature The possible values are:
COMBOCARD = Combo Card
DSRP = Digital Secure Remote Payment
extraPaymentInfo.type
String
Optional
Feature type, if the value of extraPaymentInfo.id is DSRP The possible values are:
UCAF = Universal Cardholder Authentication Field
ICC = Integrated Circuit Card
The default value is UCAF.
TransactionDetail
The TransactionDetail object contains the transaction information for the user's purchase.
"TransactionDetail" data structure elements:
Key
Type
Required
Description
orderNumber
String
Required
Order number of the transaction The following characters are allowed: [A-Z][a-z][0-9,-]
merchant
Object
Required
Data structure containing merchant information
merchant.name
String
Required
Merchant name
merchant.url
String
Required
Merchant domain URL The maximum length is 100 characters.
merchant.id
String
Conditional
A unique identifier, known as the Merchant Unique ID, is assigned by either merchant or the Payment Gateway (PG) or Payment Orchestrator (PO) when a merchant is onboarded into their system. This ID is required in specific scenarios, namely when onboarding as a PG or PO with Samsung, or if the token brand is "mada" or the merchantChoiceBrands.brands includes "mada". The character limit for this ID varies: 15 characters for "mada" token brands and 45 characters for all other cases
merchant.countryCode
String
Required
Merchant country code ISO-3166-1 alpha-2
amount
Object
Required
Data structure containing the payment amount
amount.option
String
Required
Display format for the total amount on the payment sheet The possible values are:
FORMAT_TOTAL_ESTIMATED_AMOUNT = Display "Total (Estimated amount)" and total amount
FORMAT_TOTAL_PRICE_ONLY = Display the total amount only
amount.currency
String
Required
Currency code The maximum length is 3 characters.
amount.total
String
Required
Total payment amount in the currency specified by amount.currency The amount must be an integer (for example, 300) or in a format valid for the currency (such as 2 decimal places after a separator, for example, 300.50).
type
String
Optional
Transaction type This value is specifically supported for mada tokens and will not apply to other token types. The possible values are:
PURCHASE
PREAUTHORIZATION
The default value is PURCHASE.
PaymentCredential
The PaymentCredential object contains the payment credential information generated by the Samsung Wallet application on the user's mobile device.
PaymentCredential data structure elements:
Key
Type
Required
Description
card_brand
String
Required
Brand of the payment card
card_last4digit
Object
Required
Last 4 digits of the card number
3DS
Object
Required
Data structure containing the generated 3DS data
3DS.type
String
Optional
3DS type The value is S for Samsung Pay.
3DS.version
String
Required
3DS version The value for the current version is 100.
3DS.data
String
Required
Encrypted payment credential data
recurring_payment
boolean
Required
Value if credential is enabled for recurring The default value is false.
encryptedMessage
String
Conditional
Encrypted string(JWE) that contains billing address, cardholder name and CPF when required by partner. It can be decrypted in the same way as Payment Credentials.
EncryptedMessage
The decrypted encryptedMessage object in PaymentCredential object contains billing address, cardholder name and CPF when required by partner.
"EncryptedMessage" data structure elements.
Key
Type
Required
Description
billingAddress
Object
Conditional
Billing Address
billingAddress.addressLine1
String
Required
Address Line 1
billingAddress.addressLine2
String
Optional
Address Line 2
billingAddress.city
String
Required
City
billingAddress.state
String
Conditional
State
billingAddress.countryCode
String
Required
Country Code (ISO 3166-1 alpha-3)
billingAddress.postalCode
String
Required
Postal Code
cardholderName
String
Conditional
Cardholder Name
cpf
Object
Conditional
Brazilian CPF
cpf.name
String
Required
The full name of the individual associated with the CPF.
cpf.number
String
Required
The Brazilian taxpayer number (CPF), consisting of exactly 11 digits, without hyphens or dots.
PaymentResult
The PaymentResult object contains the payment result information during transaction processing, and after the payment is processed with PG network.
PaymentResult data structure elements.
Key
Type
Required
Description
status
String
Required
Payment status The possible values are:
CHARGED = payment was charge successfully
CANCELED = payment was canceled by either user, merchant, or acquirer
REJECTED = payment was rejected by acquirer
ERRED = an error occurred during the payment process
provider
String
Optional
Payment provider (PG) name
3.3.7 Partner Checklist
Checklist for Samsung Pay Web Checkout.
On the merchant website, verify if the following functions works as expected:
Samsung Pay is available in the payment options section of the website.
Samsung Pay logo is displayed correctly in the payment options section.
After the Samsung Pay payment option is selected, the Account/Scan QR and Email input options are displayed, and redirects the user to the Samsung Wallet app on their mobile device.
For the Account option, “Request to pay” and “Cancel” buttons are displayed.
For the Email option, “Next” and “Cancel” buttons, and a way to reset ID are displayed.
For the Scan QR option, the request automatically times out if you wait for more than 5 minutes, and you are redirected to the checkout screen.
Once redirected to the Samsung Wallet app, “Pay” and “Cancel” buttons are displayed.
On a mobile browser, after the Samsung Pay payment option is selected, “Continue with Samsung Pay” button is displayed.
Samsung Checkout screen is displayed.
The merchant domain name is displayed.
The order summary which contains the amount due, and product name is displayed.
The payment method selected is “Samsung Wallet”.
The contact information displays the customer’s name, phone, and email. You should be able to modify this information, if needed.
“Continue” and “Cancel” buttons are displayed.
Note:These are relevant if you are executing an end-to-end test. You can skip these tests if you are using a test transaction setup.
On the Samsung Wallet app via your test device, verify if the following functions works as expected:
A default card is displayed on the payment sheet.
The card name and last 4 digits of the card is displayed on the payment sheet.
You are able to change the card when multiple cards are enrolled in Samsung Pay.
If you requested for the transaction using billingAddress parameter, the billing address is displayed on the payment sheet.
The billing address can be filled and modified.
Depending on the amount.option parameter, the payment amount is displayed as “Total” or “Total (estimated amount)”.
The merchant name is displayed on the payment sheet.
The PIN/biometric authentication option is displayed to proceed with payment confirmation.
The “Verified” checkmark is displayed in blue upon payment confirmation.
If you are testing with actual cards, and Samsung Wallet is in production environment, confirm the transaction notification on the mobile phone is displayed once the purchase is made.
On transaction completion, verify the following on the merchant website:
The payment completion screen is displayed on the mobile or non-mobile device, depending where the transaction is initiated.
You are able to initiate a payment using Samsung Pay with a card already added for the merchant’s website (basic card).
Manage Your Cookies
We use cookies to improve your experience on our website and to show you relevant
advertising. Manage you settings for our cookies below.
Essential Cookies
These cookies are essential as they enable you to move around the website. This
category cannot be disabled.
Company
Domain
Samsung Electronics
.samsungdeveloperconference.com
Analytical/Performance Cookies
These cookies collect information about how you use our website. for example which
pages you visit most often. All information these cookies collect is used to improve
how the website works.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Functionality Cookies
These cookies allow our website to remember choices you make (such as your user name, language or the region your are in) and
tailor the website to provide enhanced features and content for you.
Company
Domain
LinkedIn
.ads.linkedin.com, .linkedin.com
Advertising Cookies
These cookies gather information about your browser habits. They remember that
you've visited our website and share this information with other organizations such
as advertisers.
Company
Domain
LinkedIn
.linkedin.com
Meta (formerly Facebook)
.samsungdeveloperconference.com
Google Inc.
.samsungdeveloperconference.com
Preferences Submitted
You have successfully updated your cookie preferences.