Uh oh! We couldn’t find any match.

Please try other search keywords.

Bixby Developer Center

Guides

Supporting Payments

To allow users to pay for purchases, Bixby provides native integration of Samsung Payment Services (SPS). Bixby's implementation supports the following payment gateways:

  • Adyen
  • Authorize.Net
  • BlueSnap
  • Braintree Blue
  • Braintree Orange
  • Merchant e-Solutions
  • Stripe
  • WePay

If your region is not currently supported by SPS, or you need to communicate with a different payment provider, you can use HTTP Delivery.

Note

Support for Samsung Payment Services is currently limited to specific developers. If you are interested in integrating Samsung Payment in your capsule, reach out to the Samsung Developer Relations team for more information.

HTTP Delivery

If you're using another payment provider, you can use http-delivery to have SPS communicate directly with their payment API.

Before You Start

If you choose this option, you'll need to have the following documentation on your compliance with the PCI Data Security Standard:

  • An Attestation of Compliance (AOC), which can be obtained from an appropriate PCI Self-Assessment Questionnaire
  • A current Attestation of Scan Compliance for security vulnerabilities from a PCI Approved Scanning Vendor (ASV)
  • Technical integration documentation for your service's API, including its production URL

After approval, Samsung Developer Relations will contact you and request this documentation.

Local HTTP Endpoints

Using http-delivery, you'll need to include keys that define the details of the SPS payment, including:

  • merchant ID
  • merchant URL
  • supported cards
  • whether CVV verification is required
  • payment details such as amount, currency, and itemized details

Here is an example of how the payment-methods block could look with SPS information:

action-endpoints {
action-endpoint (PaymentAction) {
local-endpoint ("PaymentAction.js")
accepted-inputs (payInfo, taxInfo, shipInfo, $vivContext, $sps)
payment-methods {
sps {
merchant-name (transfer-money-to-account)
http-delivery {
url {
template (https://transfer-money-to-account.com/purchase/post)
}
// optional, but required if testing in Simulator
test-api-hostname (https://transfer-money-to-account.com/)
supported-card (VISA)
supported-card (MASTER)
cvv-verification (false)
}
payment {
amount (payInfo.amount)
currency (payInfo.currency)
items (payInfo.items) {
where-each (item) {
item {
name ("#{value(item.name)}")
amount (item.amount)
count (item.count)
}
}
}
tax {
amount (taxInfo.amount)
}
shipping {
amount (shippingInfo.amount)
}
}
}
}
}
}
Note

The url key is optional. If it is not specified, you need to add it to the options in your JavaScript: options.url = "https://transfer-money-to-account".

The JavaScript implementation in PaymentAction.js could look like this:

var http = require('http');

module.exports.function = function paymentAction(payInfo, taxInfo, shipInfo, $vivContext, $sps) {
var options = {};
options.headers = {
"Content-Type" : "application/json",
"User" : "blah"
};
var body = {
product_id: 916598,
card_number: "{{credit_card_number}}"
};
options.body = JSON.stringify(body);
var response = http.spsProxyPost(options);
return response;
}

Remote HTTP Endpoints

With remote endpoints, you provide the payments details as you do with local endpoints. However, you also provide headers and body details using variables and functions in the remote-endpoint block of your endpoints.bxb file:

...
action-endpoints {
action-endpoint (paymentAction) {
payment-methods {
sps {
merchant-name (transfer-money-to-account)
http-delivery {
url {
template (https://transfer-money-to-account.com/purchase/post)
}
spreedly-receiver-type (test)
// optional, but required if testing in Simulator
test-api-hostname (https://transfer-money-to-account.com/)
supported-card (VISA)
supported-card (MASTER)
cvv-verification (true)
}
payment {
amount (payInfo.amount)
currency (payInfo.currency)
// Both 'items' and 'item' are optional, but at least one needs to be present.
// It is possible to have multiple 'items' and 'item's and a combination of both.
items (payInfo.items) {
where-each (item) {
item {
name("#{value(item.name)}")
amount(item.amount)
count(item.count) // Optional. Should be specified when it applies.
}
}
}
}
}
}
remote-endpoint (https://transfer-money-to-account.com) {
headers {
header (some-merchant-api-header:some-header-value)
}
body {
template ("{ \"product_id\": \"916598\", \"card_number\": \"{{credit_card_number}}\", \"cvv\": \"{{credit_card_verification_value}}\" }\"")
}
method (POST)
}
}
}
...

For more information on SPS payments, read about related keys in the Reference Guide.

SPS Payment Variables and Functions

As part of the body or headers, you can include a number of credit card variables:

VariableDescription
credit_card_tokenThe Spreedly payment method token
credit_card_numberThe full credit card number of the payment method
credit_card_verification_valueThe CVV of the credit card
credit_card_first_nameThe card holder’s first name
credit_card_last_nameThe card holder’s last name
credit_card_monthThe numerical month of the credit card’s expiration date (example: 4 for April)
credit_card_yearThe four digit year of the credit card’s expiration date (example: 2015)
credit_card_expiration_dateThe credit card’s expiration date (example: 2020-04-01)
credit_card_created_atThe credit card’s created_at date (example: 2016-07-13 14:14:03 UTC)
credit_card_updated_atThe credit card’s updated_at date (example: 2016-07-13 14:14:03 UTC)
credit_card_typeThe type, or brand, of the card. Allowable values are: visa, master, american_express, discover, jcb, diners_club, dankort, maestro, carnet
credit_card_emailThe card holder’s email address
credit_card_address1The card holder’s billing address line 1
credit_card_address2The card holder’s billing address line 2
credit_card_cityThe card holder’s billing city
credit_card_stateThe card holder’s billing state
credit_card_zipThe card holder’s billing zip
credit_card_countryThe card holder’s billing country
credit_card_phone_numberThe card holder’s phone number

Additionally, you can use the following functions in requests:

FunctionDescription
aesEncrypt contents using the Advanced Encryption Standard (AES) symmetric encryption algorithm.
base64Base 64 encode contents.
Example: {{#base64}}contents to encode{{/base64}}
binary_security_tokenFor receivers that require an x509 certificate (for example: Mastercard), the binary_security_token inserts the Base64 encoded certificate.
bytes_hexTakes a hex string and turns it into raw bytes. This function is rarely useful by itself, but can be helpful when paired with functions such as aes.<
Example: {{#bytes_hex}}hexadecimal string to decode{{/bytes_hex}}
card_type_mappingOutput a custom card brand.
Example: {{#card_type_mapping}}brand:output,brand:output{{/card_type_mapping}}
Any card types whose value is not mapped in the function body will have the default credit_card_type value used. For example, if Diners Club card type is not specified the default diners_club would be output.
credit_card?If the payment method is a credit card payment method, evaluates to true. You can use this to conditionally evaluate a section.
Example: {{#credit_card?}}I'm a credit card payment method{{/credit_card?}}
digestDigests contents using the specified digest algorithm. The digest algorithm can be one of sha512 or sha256. Because the raw output is in binary form you will often use the digest function embedded within another encoding function, such as base64, to produce web-safe output.
Example: {{#base64}}{{#digest}}sha512,{{ credit_card_number }}{{/digest}}{{/base64}}
format_dateParse a date value to a specific string format.
Example: {{#format_date}}%m%y,{{credit_card_expiration_date}}{{/format_date}}
Parse a date value to a specific string format. The format specifier syntax is based on the posix date format.
gpgFor some SFTP endpoints (batch export), the receiver requires the uploaded file to be encrypted using GnuPG and their public key.
Example: {{#gpg}}full pem,recipient identity,file template to encrypt{{/gpg}}
The gpg function takes the public key in PEM form as the first argument, the target identity as the second (email address of the recipient), and the content to encrypt as the third. The third argument will be your entire templated export which can include other receiver functions are variables.
hex_bytesTakes a byte string and turns it into a hex string.
Example: {{#hex_bytes}}delimiter,byte string to encode{{/hex_bytes}}
hex_digestComputes the HMAC of a given payload. The payload is returned as a hexadecimal string. The digest algorithm can be any of SHA1, SHA256, or SHA512.
Example: {{#hmac}}digest algorithm,secret key,payload whose digest is desired{{/hmac}}
lastGet the last characters of a value.
Example: {{#last}}num,contents{{/last}}
md5Calculate the MD5 digest of the contents.
Example: {{#md5}}value to digest{{/md5}}
replaceReplaces every instance of a given pattern with a new value in the content. Neither the pattern nor replacement can themselves contain commas.
Example: {{#replace}}pattern,replacement,content{{/replace}}
rsaEncrypts contents using RSA public key cryptography. The certificate value must be in PEM format. The currently available padding schemes include: pkcs1 or oaep. Because the raw output is in binary form you will often use the rsa function embedded within another encoding function, such as base64, to produce web-safe output.
Example: {{#rsa}}certificate-pem,padding-scheme,contents to encrypt{{/rsa}}
rsa_signSigns (and base64 encodes) contents using the private key configured for the receiver. Requires a receiver pre-configured with an encryption certificate. The digest algorithm can be sha512 or sha256.
Example: {{#rsa_sign}}digest-algorithm,contents to sign{{/rsa_sign}}
triple_desEncrypt contents using the Triple DES (3DES) symmetric encryption algorithm. The encryption mode can be CBC, CFB, OFB, or CTR. Because the raw output is in binary form you will often use the triple_des function embedded within another encoding function, such as base64, to produce web-safe output. Note that 3DES encryption is not generally acceptable for use in a PCI-compliant context, as 3DES encryption can be broken in a trivial amount of time on normal desktop computers and cell phones. You should instead use alternative mechanisms, such as AES encryption, in most contexts.
Example: {{#triple_des}}mode,initialization vector as byte array,encryption key,data{{/triple_des}}
truncateTruncate a value to a given size.
Example: {{#truncate}}length,contents{{/truncate}}
utc_timestampInserts an ISO 8601 formatted timestamp at the time of export.
Example: {{#utc_timestamp}}{{/utc_timestamp}}
xml_dsigGenerate the WS-Security XML digital signature for a given SOAP envelope. Requires a receiver pre-configured with an encryption certificate.
Example: {{#xml_dsig}}full XML body{{/xml_dsig}}

Passing a User's Non-Sensitive Card Information

You can add a special $paymentCard input to your accepted inputs if you need to access non-sensitive information about the card confirmed by the user.

Note

This parameter is only available in actions that specify sps as their payment-methods in your action-endpoints.

accepted-inputs (payInfo, taxInfo, shipInfo, $vivContext, $paymentCard)

Here is the information that you can access via the $paymentCard parameter:

  • last4: The last four digits of the credit card. Example: 9999
  • address1: The first line of the billing address. Example: 1445 Norwood Ave
  • address1: The second line of the billing address, if needed. This is typically used for apartment or unit numbers. Example Building 5
  • city: The city of the billing address. Example: Itasca
  • state: The state of the billing address. Example: IL
  • zip: The zip code of the billing address. Example: 60143
  • country: The country of the billing address. Example: US
  • phone: The phone number of the customer, if provided. Example: 18885551212

Here is an example of using $paymentCard to get the billing address information.

First, create an action model:

action (AccessPaymentCard) {
type(Commit)
collect {
input (dummyInput) {
type (viv.core.Integer)
}
}
output (viv.core.Text)
}

In your corresponding JavaScript file, access the $paymentCard.%information% parameter to return the billing address information.

//AccessPaymentCard.js
module.exports.function = function paymentAction (dummyInput, $vivContext, $paymentCard) {
if ($paymentCard) {
console.log("$paymentCard.last4: " + $paymentCard.last4)
console.log("$paymentCard.address1: " + $paymentCard.address1)
console.log("$paymentCard.address2: " + $paymentCard.address2)
console.log("$paymentCard.city: " + $paymentCard.city)
console.log("$paymentCard.state: " + $paymentCard.state)
console.log("$paymentCard.zip: " + $paymentCard.zip)
console.log("$paymentCard.country: " + $paymentCard.country)
console.log("$paymentCard.phone: " + $paymentCard.phone)
} else {
console.log("$paymentCard is null")
}
...

You would then need to configure your endpoints for this action like below, including making sure that you set up the proper accepted-inputs for your endpoint:

action-endpoint (AccessPaymentCard) {
accepted-inputs (dummyInput, $vivContext, $paymentCard)
local-endpoint ("AccessPaymentCard.js")
}