3.4 Save to Pay

3.4.1 Overview

Save to Pay (S2P) is a secure integration service by Samsung Pay that enables partners to store and access user payment credentials for future transactions. The communication between the partner’s backend and the Save to Pay server is protected by Mutual SSL (Two-Way SSL) authentication, ensuring that both the client and server validate each other's identities.

Key Highlights:

  • Uses a custom Certificate Authority (CA) managed by Samsung Pay TechOps.
  • Requires IP allowlisting for both staging and production environments.
  • Communication is secured over TLS 1.2.
  • Involves both inbound (Partner → S2P) and outbound (S2P → Partner) API communications, secured via SSL and authenticated with client certificates and headers.



3.4.2 Endpoints

There are 2 endpoints available - Staging & Production.

  • Staging will be used for development and integration testing.
  • Access to these endpoints is restricted to allowlisted IP addresses. Partner should provide the external IP addresses during the onboarding process.
  • Supported protocols - TLSv1.2
Staging

https://s2p-api.stg.mpay.samsung.com

Production

https://s2p-api.mpay.samsung.com


3.4.3 Onboarding Steps

To begin integration, follow these onboarding steps:

Step 1: Submit a Certificate Signing Request (CSR)

Partners must generate and send a CSR to Samsung, along with the following details:

  • Common Name (CN) for the client certificate
  • Partner server base URL for receiving outbound notifications from the S2P server
  • External IP address to be added to the access allowlist

Step 2: Receive Certificate and Partner ID

  • Samsung will sign the CSR using its internal CA and return the client certificate.
  • A unique Partner ID will be issued for each environment.
  • This Partner ID must be included in the headers of every request made to the S2P server.

3.4.4 Authentication Overview

Mutual SSL is used for both inbound and outbound communication between the partner and the Save to Pay system.

INBOUND: Partner → Save to Pay Server

  • All requests must be secured with mutual SSL.
  • Partners connect using the client certificate issued by Samsung.
  • Every request must include the Partner ID in the header.
  • Partner IDs are environment-specific (different for staging and production).

OUTBOUND: Save to Pay Server → Partner

  • S2P communicates with partner servers over mutual SSL.
  • Samsung will use a client certificate signed by the partner’s CA.
  • Partner must be able to validate S2P’s certificate for inbound requests.

3.4.5 Security Protocols

  • Protocol: TLS v1.2
  • Authentication: Mutual SSL (Two-Way TLS)
  • Certificates:
    • Partner-to-S2P: Samsung issues the client certificate.
    • S2P-to-Partner: Partner issues the client certificate to Samsung.

3.4.6 Best Practices

The best practices are:

  • Keep your client certificate secure and monitor expiration dates.
  • Log and monitor all inbound/outbound requests for verification and debugging.
  • Maintain a staging environment for ongoing testing.

3.4.7 External API Specification

The External API Specification in the context of Samsung's Save to Pay (S2P) service refers to the structured guidelines and protocols that define how external partner systems can securely interact with the S2P platform. This specification encompasses authentication methods, data formats, API endpoints, and integration workflows to ensure seamless and secure provisioning of payment cards into the Samsung Wallet app.

3.4.8 Integration Workflow

The integration involves several key steps:

Initialization & UI Setup

Step 1–2: Register Session

  • The partner server initiates the flow by registering with the S2P server.
  • On success, it receives:
    • regId: A unique session identifier (must be cached for session tracking).
    • welcomeUrl: A hosted UI URL that guides the user through the card addition process.

Step 3: Display Welcome UI

  • The partner's frontend embeds the welcomeUrl UI (typically in an <iframe>).
  • The UI shows a QR code and clear instructions for the user to continue.

User Interaction

Step 4: User Launches Samsung Wallet (SPay WA)

  • The user opens the Samsung Wallet app and scans the QR code shown on the Welcome UI.
  • If the app is not installed, the UI directs the user to:
    • Download the Samsung Wallet app.
    • Sign in with their Samsung Account.

Session Linking & Device Validation

Step 5–6: Initiate Request & Device Association

  • SPay WA scans the QR code and triggers an initiate request to the S2P server.
  • S2P validates the payload and links the device info with the regId.
  • The server also forwards the device metadata to the partner server:
    • Device ID
    • Wallet ID
    • User ID
  • The Welcome UI updates to show that linking was successful.

Card Pre-Provisioning

Step 7–8: Partner Pre-Provisions Card

  • The partner server contacts the issuer to:
    • Pre-provision the card.
    • Retrieve the encrypted issuerBlob (which contains secure card/token information).

Step 9: Return IssuerBlob

  • The partner server includes the issuerBlob in its notify response back to the S2P server.
  • This blob:
    • Is encrypted (only the issuer can decrypt it).
    • Is device- and wallet-specific (only usable by the original device).
    • Format depends on the issuer.

Step 10: Deliver to Device

  • The S2P server includes the issuerBlob and any other metadata in the initiate response back to the Spay WA.

Tokenization

Steps 11–16: Add Token in Samsung Pay

  • SPay WA initiates the standard tokenization process using the issuerBlob.
  • The token is securely added to the Samsung Wallet for use in NFC or online transactions.

Completion & Confirmation

Step 17: Notify S2P Server

  • After successful provisioning, SPay WA notifies the S2P server that the card/token was added successfully for the given regId.

Step 18: Notify Partner

  • The S2P server sends a final callback to the partner server confirming the process is completed for the regId.

3.4.9 Data Types

Type

JSON Type

Format

Description

String

string

Size: 2048

Boolean

boolean

Object

object

Enum

string

Pattern: [A-Za-z0-9_]{1,256

Values from a limited set are only allowed. Each field of type Enum will define the values allowed.

PhoneNumber

string

Pattern: [0-9+()-]+

UUID

string

Pattern: [a-zA-Z0-9-_]{26,128}

Unique identifier

URL

string

Size: 2048

Must be an absolute URL defined by RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax. Supported schemes - http, https

Timestamp

number

int64 - signed 64 bits

Unix epoch time in milliseconds.

CountryCode

string

Size: 2

Unique identifier


3.4.10 Inbound API Specification – Save2Pay

The Inbound API Specification for Save2Pay defines the protocols and requirements for partner servers to interact with the Save2Pay system. This specification ensures secure and standardized communication during the push provisioning process.

General Contract

Base URL

https://s2p-api.mpay.samsung.com/ext/v1

Security

Mutual SSL is required.

Common Headers

Header Name

Type

Validation

Description

Request-Id

UUID

Required

Unique identifier for the request

Partner-Id

UUID

Required

Unique identifier that is provided to Partner during onboarding.

Partner-Id

UUID

Required

Request-Id echoed back in the response headers

Common HTTP Error Codes

HTTP Code

Description

Application Code

Message

400

Bad Request

400.1

Invalid Data

500

Internal Server Error

500.1

Internal Server Error

503

Service Not Available

503.1

Service Temporarily Unavailable (Retry-After header is required)

503

Service Not Available

503.2

API Temporarily Unavailable (Retry-After header is required)

3.4.11 Registration

Partner server registers a session for the user. As a result, a unique registration ID will be generated. Partner server should make sure that this is called only once for one card.

A welcomeURL will also be returned. Partner server can display the welcomeURL in browser or email. Upon rendering, a QR code will be displayed and users can use their SPay WA to scan the QR code.

WelcomeURL has an expiration date, partner server should check if it's still valid before rendering. If it's expired, a GET call will return the new URL.

Request

POST /registrations

Body

Key

Type

Validation

Description

Example

registration.email

String

Optional

User email address

registration.enforceEmailMatching

Boolean. Default is false.

Optional

Enforce only SPay WA with the same email address can provision. Enforcement is only against the email address that's provided by the partner.

true

registration.hideEmail

Boolean. Default is false

Optional

Hide email field

registration.phone

PhoneNumber

Optional

User phone number

registration.enforcePhoneMatching

Boolean

Optional. Default is false

Enforce only SPay WA with the same phone number can provision. Enforcement is only against the phone number that's provided by the partner.

true

registration.hidePhone

Boolean

Optional. Default is false

Hide phone field

registration.welcomeCallbackUrl

URL

Optional

Callback URL that the Welcome UI will redirect to once the user successfully linked a SPay WA account

registration.allowOfflineCommunication

Boolean

Optional. Default is false.

If true, S2P will communicate to the user via email and/or phone number to facilitate the provisioning process

registration.data

Object

Optional

Arbitrary data blob that'll be passed to the device when an account is linked.

registration.custom.cardName

String

Required

Card name that'll show on the welcome page.

registration.custom.cardArtUrl

URL

Required

CardArt URL that'll show on the welcome page

registration.custom.partnerName

String

Required

Partner name that'll show on the welcome page.

registration.custom.partnerLogoUrl

URL

Required

Partner Logo URL that'll show on the welcome page.

registration.custom.partnerTncUrl

URL

Optional

Partner TnC URL that'll show on the welcome page.

registration.id

UUID

Required

Registration ID that identifies this session

registration.status

Enum - PENDING, LINKED

Required

Registration status

PENDING

registration.welcomeUrlExpiration

Timestamp

Required

WelcomeUrl expiration timestamp in milliseconds

Response

Status

HTTP/1.1 201 Created

Header

Name

Value

Content-Type

application/json

Example

POST /ext/v1/registrations
{
 "email": "user@gmail.com",
 "enforceEmailMatching": true,
 "phone": "14089998888",
 "enforcePhoneMatching": true,
 "custom": {
 "cardName": "XYZ Bank Credit Card",
 "cardArtUrl": "https://xyz.com/cardArt.png",
 "partnerName": "XYZ Bank",
 "partnerLogoUrl": "https://xyz.com/logo.png"
 }
}
HTTP/1.1 201 Created
{
 "id": "395ce2e29485442cbd9bacdc77105126",
 "welcomeUrl": 
"https://s2p.stg.mpay.samsung.com/v1/welcome/eyJlbmMiOiJBMjU2R0NNIiw
iYWxnIjoiZGlyIn0..S0dNxrskDKjw8SbH.kG4UQhfwKkDNqrvIihkAqShq_JAYb99ct
TiZdZrwRN-qLhuZj4iMUYv1SAGEHAVYxlUAmaRWA.TlEKqcErR0jklC-fNQKcVA",
 "status": "PENDING",
 "welcomeUrlExpiration": 1505953396844
}

Get registration

Check existing registration status and/or get new welcomeUrl.

Request
GET /registrations/{regId}

Headers

Name

Value

Validation

partner-id

Partner id value assigned by Samsung Wallet

Required

Response

Status

HTTP/1.1 200 OK

Status

Name

Value

Content-Type

application/json

Body

Key

Type

Validation

Description

Example

registration.id

UUID

Required

Registration ID that identify this session

registration.status

Enum - PENDING, LINKED

Required

Registration status

PENDING

registration.welcomeUrl

URL

Required

This is the URL that partner can show to the user as an iFrame a separate page. It shows the QRCode and optionally user can enter email and phone number.

registration.welcomeUrlExpiration

Timestamp

Required

WelcomeUrl expiration timestamp in milliseconds

Example
HTTP/1.1 200 OK

{
"id": "395ce2e29485442cbd9bacdc77105126",
"welcomeUrl":
"https://s2p.stg.mpay.samsung.com/v1/welcome/eyJlbmMiOiJBMjU2R0NNIiw
iYWxnIjoiZGlyIn0..S0dNxrskDKjw8SbH.kG4UQhfwKkDNqrvIihkAqShq_JAYb99ct
TiZdZrwRN-qLhuZj4iMUYv1SAGEHAVYxlUAmaRWA.TlEKqcErR0jklC-fNQKcVA",
"status": "PENDING",
"welcomeUrlExpiration": 1505953396844
}

Errors

Common HTTP Error Codes

HTTP Code

Description

Application Code

Message

400

Bad Request

400.1

Invalid Data

500

Internal Server Error

500.1

Internal Server Error

503

Service Not Available

503.1

Service Temporarily Unavailable (Retry-After header is required)

503

Service Not Available

503.2

API Temporarily Unavailable (Retry-After header is required)

3.4.12 Outbound to Partner

The Outbound API Specification for Save2Pay defines how the Save2Pay server communicates with partner servers during the Push provisioning process. This specification ensures secure and standardized communication between Save2Pay and its partners.

General Contract

Base URL

Base URL for outbound APIs. To be provided by the partner during the onboarding process.

Security

Mutual SSL is required.

Common Headers

Header Name

Type

Validation

Description

Request-Id

UUID

Required

Unique identifier for the request

Partner-Id

UUID

Required

Unique identifier that is provided to Partner during onboarding

Response-Id

UUID

Required

Request-Id echoed back in the response headers


3.4.13 Event Notification

Notify partner for events.

Request

POST /notifications

Body

Key

Description

Type

Validation

Example

event.regId

Registration ID

UUID

Required

event.type

Event type

Enum. Refer to Event Types and Errors for details

Required

event.error

More information about the failure

Enum. Refer to Event Types and Errors for details.

event.desc

Additional description of the event

String

Optional

User

Container for user information

Object

Conditional. Will be present for Payment cards

user.id

Samsung account ID

String

Required

emailMatches

Is true if the email provided in the registration request matches with Samsung account email.

Boolean

Conditional. It is present only if an email was provided in the registration request.

phoneMatches

Is true if the phone number provided in the registration request matches with device phone number

Boolean

Conditional. It is present only if a phone number was provided in the registration request.

device

Container for device information

Object

Conditional. Will be present for Payment cards

device.id

Device ID

String

Required

device.imeiLast4

Last 4 of device IMEI

String. Size: 4

Optional

device.serialLast4

Last 4 of device serial number

String. Size: 4

Optional

device.locale.country

Device country code

CountryCode

Optional

wallet

Container for wallet information

Object

Conditional. Will be present for Payment cards

wallet.id

Wallet ID

String

Required

Event Types and Errors

Type

Error

Description

WA_READY

Wallet app is ready for provisioning

WA_PROVISIONED

Indicates card was successfully provisioned into the wallet

WA_PROVISION_FAILURE

Indicates provisioning failed for some unknown reason

WA_PROVISION_FAILURE

CARD_ALREADY_PRESENT

Indicates card is already present.

Response

Status

HTTP/1.1 200 OK

Header

Name

Value

Content-Type

application/json

Body

card.data.encryptedData

Description

Encrypted PAN data that will be returned to the device to provision the card

Type

String. Size: 65536

Validation

Conditional. Required if card data was not provided in the registration request.

Example

Example

POST /notifications
{
 "event": {
 "regId": "395ce2e29485442cbd9bacdc77105126",
 "type": "WA_READY"
 },
 "emailMatches": true,
 "phoneMatches": true,
 "user": {
 "id": "RcSm3gWJT9mXgFWy5sG123"
 },
 "wallet": {
 "id": "GpcCUgejS9GIiH8zch1111"
 },
 "device": {
 "id": "MTUxMTE5MDAwMjAwMDM1N999",
 "imeiLast4": "6166",
 "locale": {
 "country": "US"
 },
 "serialLast4": "4934"
 }
}
HTTP/1.1 200 OK
{
 "card": {
 "data": {
 "encryptedData": "*****"
 }
 }
}

3.4.14 Save to Pay JavaScript Library

JavaScript Library

interface saveToPayUI {
 /** 
 * Shows the welcome UI. Redirects to welcomeCallbackUrl if it was 
provided in the registration request when the page reaches one of 
the final states. 
 */
 static void showWelcomeModal(S2PRequest r);
 /**
 * Shows the welcome UI. Resolves the promise with the status and 
optionally details after the welcome UI is closed.
 */
 static Promise <S2PResponse> showWelcomeModalPromise(S2PRequest 
r);
 
 /**
 * API to close the modal
 */
 static void closeWelcomeModal(); 
};
dictionary S2PRequest {
 /**
 * welcomeUrl provided by Save2Pay server in the registration 
response. 
 */
 required DOMString welcomeUrl;
};
dictionary S2PResponse {
 required Status status,
 /** 
 * true if triggered by iframe closing (by user or parent page)
 * false if the status is one of the final statuses, not triggered 
by iframe closing. This can only happen in mobile android case.
 */
 required boolean isIframeClosed,
 /**
 * Optional error information if the status is 'FAILURE'
 */
 Details details
};
dictionary Details {
 required ErrorCode errorCode;
 DOMString message;
};
enum Status {
 "SUCCESS",
 "FAILURE",
 "DEVICE_NOT_SUPPORTED",
 "DEFAULT_PENDING"
};
enum ErrorCode {
 "INVALID_INPUT",
 "PROVISION_FAILURE",
 "NETWORK_ERROR",
 "UNKNOWN_ERROR",
 "CARD_ALREADY_PRESENT",
 "CANCELED"
};

USAGE

Code Block -1: HTML

<script 
src="https://spay.samsung.com/s2p/libs/js/0.0.4/s2p.min.js"></script>

Code Block -2: JavaScript - Redirect

var input = {
 "welcomeUrl": 
'https://s2p.mpay.samsung.com/v1/welcome/eyJlbmMiOiJBMjU2R0NNIiwiYWx
nIjoiZGlyIn0..eLtgW8qp56CIEzo2.mh34gjebgYP_M7-
gW0SbDL3CkaPlP7RtvMC8fe-TmQ2IPMP2rcC1A39qODbVW2sCHiArbooahBE77LPvL8NhKkaPI6MHYNL-Yz6GQx0Sjw.xfRTYjpdZxRnMlQ8Ffe6pg'
}
window.spay.saveToPayUI.showWelcomeModal(input)

Code Block- 3: JavaScript - Promise

var request = {
 "welcomeUrl": 
'https://s2p.mpay.samsung.com/v1/welcome/eyJlbmMiOiJBMjU2R0NNIiwiYWx
nIjoiZGlyIn0..eLtgW8qp56CIEzo2.mh34gjebgYP_M7-
gW0SbDL3CkaPlP7RtvMC8fe-TmQ2IPMP2rcC1A39qODbVW2sCHiArbooahBE77LPvL8NhKkaPI6MHYNL-Yz6GQx0Sjw.xfRTYjpdZxRnMlQ8Ffe6pg'
}
function successCallback(response) {
 console.log(response.status)
}
function failureCallback(error) {
 console.log(error)
}
window.spay.saveToPayUI.showWelcomeModalPromise(request).then(succes
sCallback, failureCallback)

Promise Resolution

Device Type

Description

Desktop, Tablet & Mobile - iOS

JS library will resolve the promise -
1. When the iframe is closed by the user.
2. closeWelcomeModal function is invoked.

Mobile - Android

JS library will resolve the promise as soon as the provisioning session ends. Or closeWelcomeModal function is invoked.
Provisioning session ends when one of the following has happened -
1. The card was successfully added.
2. There was some failure and card provisioning flow cannot continue further.
3. Timeout has happened.
4. User canceled the provisioning process.

Mobile Flows