Create your payment form
Create your payment form
Understand how to integrate the payment form into your product

Solidgate’s payment form enables tokenization of sensitive data and management of 3D Secure authentication and supports multiple payment methods.

Integration steps

This guide simplifies adding Solidgate’s payment form to your website. It covers preparing the backend, installing the SDK, creating API instances, and setting up merchant data. Additionally, it explains how to initialize the form using different JavaScript frameworks and customize its look with parameters and styles.

Setup backend

Begin by setting up your backend, a vital step for successful implementation. Utilize the Solidgate SDK for seamless integration of Solidgate’s payment form into your platforms, leveraging its intuitive transaction and payment form customization features. To initiate a charge, it is essential to supply transaction-specific information via the fields of the paymentIntent object.

chevron down chevron up
paymentIntent object

Description

The public IP address of the customer. Both IPv4 and IPv6 are supported.

Private IPs (10.0.0.0-10.255.255.255, 172.16.0.0-172.31.255.255, 192.168.0.0-192.168.255.255) will result in an ‘Invalid IP’ error.

Example

8.8.8.8

Description

Customer platform at the moment of payment.

Available values:

  • WEB - desktop
  • MOB - mobile version
  • APP - application

Example

WEB

Description

The Order ID, which must be unique, is specified in the merchant system.

Example

123456

Description

The order description in your system and for bank processing.

Example

Premium package

Description

The ID of the predefined product must be passed in UUID v4 format.

Required, for the subscription workflow.

Example

faf3b86a-1fe6-4ae5-84d4-ab0651d75db2

Description

Customer ID in the merchant’s system.

Required, for the subscription workflow.

Example

4dad42f808

Description

Order amount - integer without fractional component (i.e cents). For instance, 1020 means 10 USD and 20 cents.

Required, for the non-subscription workflow.

Example

1020

Description

The currency amount is represented in a three-letter currency code as per the ISO-4217 standard.

Required, for the non-subscription workflow.

Example

USD

Description

Customer country subject to ISO 3166-1 alpha-3.

Required, for Apple, Google Pay.

Example

GBR

Description

The country where the goods are purchased or where the seller is based is identified using the ISO-3166 alpha-3 country code.

If you are registered with international payment systems as a marketplace, this parameter is required. Being registered as a marketplace, in the context of international payment systems, typically implies that you operate a platform where numerous sellers can offer their goods or services.

Example

CHN

Description

Customer email. If no parameter is received, it will be collected automatically on payment form.

Example

test@solidgate.com

Description

Customer language settings for Solidgate payment form field translation.

Available values are listed below.

Example

en

Description

Routing payments flag for 3DS flow (enabled by Solidgate account manager).

Example

true

Description

Time (in hours) when auto-settle should be done. Value of null means that the client must request settle on its own. Minimum of 0 means that executed in the near future, and maximum value is 168 hours.

In the event of providing a settle_interval of more than 7 days, banks may settle the payment earlier.

Example

48

Description

Parameter for transaction authorization through a payment form.

Example

auth

Description

The number of payments by the customer.

Example

1

Description

Date of order creation in format YYYY-MM-DD-HH-MM-SS.

Example

2020-12-21 11:21:30

Description

Order items in UTF-8 code.

Example

item1, item2

Description

Metadata is useful for storing additional, structured information about an object. The object consists of a set of key-value pairs (e.g. “coupon_code”: “NY2018", “partner_id”: “123989"). The callback notification returns an order_metadata from the order in each state.

Example

Up to 10 fields with an upper limit of 255 characters.

Description

The object is a struct that includes parameters such as address, city, country, state, and zip_code.

If the zip_code field is provided, manual entry will not be required for it.

Example

  • zip_code and state fields should have a maximum length of 10 characters.
  • country field must be in ISO 3166-1 alpha-3 format and should be exactly 3 characters long.

All other fields should have a maximum length of 100 characters.

Description

Device of customer.

Example

iPhone 8 iOS 12.0

Description

User-agent of the customer.

Example

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (HTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36

Description

Number of retry payment.

Example

1

Description

Customer City.

Example

New Castle

Description

The website from which transaction took place.

Example

http://google.com

Description

Customer telephone.

Example

380111111111

Description

Customer first name.

Example

John

Description

Customer last name.

Example

Snow

Description

Customer birthdate in format YYYY-MM-DD.

Example

2000-11-21

Description

Provide this URL if you want to redirect a customer to your own Success Screen. If you do not provide the URL, Solidgate will direct customers to the Solidgate Success Screen.

Example

http://Merchant.example/success

Description

Provide this URL if you want to redirect a customer to your own Fail Screen. If you do not provide the URL, Solidgate will direct customers to the Solidgate Fail Screen.

Example

http://Merchant.example/fail

Description

Source of transactions on the merchant site.

Example

main_menu

Description

Source of traffic.

Example

facebook

Description

The merchant name, which can be displayed to the customers when paying via Apple.

Example

Test

Description

ID of the coupon which corresponds to the specific product discount, must be passed in UUID v4 format.

The coupon flow will only be activated when a product_id is supplied of the subscription workflow.

Without a product_id, the coupon_id will be disregarded.

Example

eb4c6e93-4c53-447a-b215-5d5786af9844

Description

The flag of the verified customer on the shop side.

⚠️ This field is deprecated and should not be used in new implementations.

Example

true

Description

A customer was detected on the merchant end to be a suspicious one.

⚠️ This field is deprecated and should not be used in new implementations.

Example

true

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
  "ip_address": "8.8.8.8",
  "platform": "WEB",
  "order_id": "123456",
  "order_description": "Premium package",
  "amount": 1020,
  "currency": "USD",
  "geo_country": "GBR",
  "customer_email": "test@solidgate.com",
  "language": "en",
  "force3ds": True,
  "settle_interval": 48,
  "type": "auth",
  "order_number": 1,
  "order_date": "2020-12-21 11:21:30",
  "order_items": "item1, item2",
  "order_metadata": {
    "coupon_code": "NY2018",
    "partner_id": "123989"
  },
  "billing_address": {
    "address": "Street 3D, Apartment 343",
    "country": "United States", 
    "state": "Delaware",
    "city": "New Castle",
    "zip_code": "03127"  
  },
  "device": "iPhone 8 iOS 12.0",
  "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (HTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
  "retry_attempt": 1,
  "geo_city": "New Castle",
  "website": "https://google.com",
  "customer_phone": "380111111111",
  "customer_first_name": "John",
  "customer_last_name": "Snow",
  "customer_date_of_birth": "2000-11-21",
  "success_url": "https://Merchant.example/success",
  "fail_url": "https://Merchant.example/fail",
  "transaction_source": "main_menu",
  "traffic_source": "facebook",
  "apple_pay_merchant_name": "Test"
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
  "ip_address": "8.8.8.8",
  "platform": "WEB",
  "order_id": "123456",
  "order_description": "Premium package",
  "product_id": "faf3b86a-1fe6-4ae5-84d4-ab0651d75db2",
  "customer_account_id": "4dad42f808",
  "geo_country": "GBR",
  "customer_email": "test@solidgate.com",
  "language": "en",
  "force3ds": True,
  "settle_interval": 48,
  "type": "auth",
  "order_number": 1,
  "order_date": "2020-12-21 11:21:30",
  "order_items": "item1, item2",
  "order_metadata": {
    "coupon_code": "NY2018",
    "partner_id": "123989"
  },
  "billing_address": {
    "address": "Street 3D, Apartment 343",
    "country": "United States",
    "state": "Delaware",
    "city": "New Castle",
    "zip_code": "03127"
  },   
  "device": "iPhone 8 iOS 12.0",
  "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (HTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
  "retry_attempt": 1,
  "geo_city": "New Castle",
  "website": "https://google.com",
  "customer_phone": "380111111111",
  "customer_first_name": "John",
  "customer_last_name": "Snow",
  "customer_date_of_birth": "2000-11-21",
  "success_url": "https://Merchant.example/success",
  "fail_url": "https://Merchant.example/fail",
  "transaction_source": "main_menu",
  "traffic_source": "facebook",
  "apple_pay_merchant_name": "Test"
}

With SDK

Step 1 Install the SDK

The Solidgate SDK should be installed in your environment:

1
npm install @solidgate/node-sdk
1
go get github.com/solidgate-tech/go-sdk
1
composer require solidgate/php-sdk
1
pip3 install solidgate-card-sdk

Step 2 Create an SDK instance

To interact with the Solidgate API, you need to create an API instance by calling the API constructor function with your Public (public_key) and Secret (secret_key) keys and as arguments.

1
2
3
const solidGate = require('@solidgate/node-sdk');

let api = new solidGate.Api("public_key", "private_key");
1
solidgateSdk := solidgate.NewSolidGateApi("public_key", "secret_key")
1
2
3
4
5
<?php

use SolidGate\API\Api;

$api = new Api('public_key', 'secret_key');
1
2
3
from solidgate import ApiClient

client = ApiClient("public_key", "secret_key")
1
val api = Api(HttpClient(), Credentials("public_key", "secret_key"))

Step 3 Form the intent data

To create a charge, you must provide some information about the transaction. This information is encapsulated in a FormInitDTO object, which is created by calling the formMerchantData function on your API instance. In the example code, the formMerchantData function is called with paymentIntent fields.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const solidGate = require('@solidgate/node-sdk');

let api = new solidGate.Api("public_key", "private_key");

let paymentIntentData = {
	/// fill it as described in documentation
}
let merchantData = api.formMerchantData(paymentIntentData);

const dataToFront = merchantData.toObject()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
	"encoding/json"
	"fmt"

	solidgate "github.com/solidgate-tech/go-sdk"
)

func main() {
	solidgateSdk := NewSolidGateApi("public_key", "secret_key")
	paymentIntent = PaymentIntent{} // fill as described in documentation
	paymentIntentBytes, err := json.Marshal(paymentIntent)

	if err != nil {
		fmt.Print(err)
	}

	formInitDto, err := solidgateSdk.FormMerchantData(paymentIntentBytes)

	if err != nil {
		fmt.Print(err)
	}

	// ...	
}
1
2
3
4
5
6
7
<?php

use SolidGate\API\Api;

$api = new Api('public_key', 'secret_key');

$response = $api->formMerchantData(['JSON payment intent // fill as described in documentation']);
1
2
3
4
5
6
7
from solidgate import ApiClient

client = ApiClient("public_key", "secret_key")

responseDTO = client.form_merchant_data({
    payment_intent_dict  // fill as described in documentation
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
val api = Api(HttpClient(), Credentials("public_key", "secret_key"))

val attributes = Attributes(mapOf(
	"amount" to 123,
	"currency" to "USD",
	"customer_email" to "testuser@example.com",
	"ip_address" to "8.8.8.8",
	"order_description" to "Test subscription",
	"order_id" to "order12345",
	"platform" to "WEB"
))

val response = api.formMerchantData(attributes)

Step 4 Pass the generated data to your frontend

After you have set up the FormInitDTO and turned it into a simple object, you can effortlessly integrate it into your front-end code by transmitting the paymentIntent encrypted String (during form initialization).

Without SDK

In addition to using the Solidgate SDK for integrating the payment form into your website, there is an alternative option to work without the SDK.


  1. Backend Preparation
    Set up your server-side code to handle the communication with Solidgate’s API using your preferred programming language and libraries.
  2. Create DTO
    Create a JSON object containing the mandatory fields for a payment transaction, and then encrypt it.
  3. Generate merchant data
    Once you have successfully encrypted the paymentIntent, pass it to your front-end code for further processing, such as initializing the payment form.
  4. Signature generation
    To initialize the Solidgate payment form, generate the signature parameter on your backend, which verifies the merchant’s request authenticity on the payment gateway server. The signature is generated from the paymentIntent encrypted String.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const publicKey = "public_key"
const secretKey = "secret_key"

const data = JSON.stringify({ 
    payment_intent_data // fill as described in documentation
});
const payloadEncrypted = encryptPayload(secretKey, data);

const formInitDTO = {
	paymentIntent: payloadEncrypted,
	merchant: publicKey,
	signature: generateSignature(publicKey, secretKey, payloadEncrypted)
}

function encryptPayload(secretKey, data) {
	let iv = crypto.randomBytes(16);
	let cipher = crypto.createCipheriv('aes-256-cbc', secretKey.substr(0, 32), iv);
	let encrypted = cipher.update(data);

	encrypted = Buffer.concat([iv, encrypted, cipher.final()]);
	return  encrypted.toString('base64').replace(/\+/g, '-').replace(/\//g, '_')
}

function generateSignature(publicKey, secretKey, attributes) {
	var hashed = CryptoJS.HmacSHA512(publicKey + attributes + publicKey, secretKey);

	return Buffer.from(hashed.toString()).toString('base64')
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$publicKey = "public_key";
$secretKey = "secret_key";

$attributes = array("json_data"); // fill as described in documentation
$encryptedFormData = generateEncryptedFormData($secretKey, $attributes);
$signature = generateSignature($publicKey, $secretKey, $encryptedFormData);
$formInitDTO = [
	"paymentIntent" => $encryptedFormData,
	"signature" => $signature,
	"merchant" => $publicKey,
];

function generateEncryptedFormData(string $secretKey, array $attributes): string
{
	$attributes = json_encode($attributes);
	$secretKey = substr($secretKey, 0, 32);

	$ivLen = openssl_cipher_iv_length('aes-256-cbc');
	$iv = openssl_random_pseudo_bytes($ivLen);

	$encrypt = openssl_encrypt($attributes, 'aes-256-cbc', $secretKey, OPENSSL_RAW_DATA, $iv);

	return strtr(base64_encode($iv . $encrypt), '+/', '-_');
}

function generateSignature(string $publicKey, string $secretKey, string $data): string
{
	return base64_encode(
		hash_hmac('sha512', $publicKey . $data . $publicKey, $secretKey)
	);
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
type FormInitDTO struct {
	PaymentIntent string
	Merchant    string
	Signature     string
}

func main() {
	publicKey := "public_key"
	secretKey := "secret_key"

	encryptedData, err := EncryptCBC([]byte(secretKey)[:32], []byte("json payment_intent"))

	if err != nil {
		return nil, err
	}

	encoded := base64.URLEncoding.EncodeToString(encryptedData)
	signature := GenerateSignature(publicKey, secretKey, []byte(encoded))

	// use formInitDTO to pass data to frontend
	formInitDTO := FormInitDTO{
		PaymentIntent: encoded,
		Merchant:      publicKey,
		Signature:     signature,
	}
}

func GenerateSignature(publicKey, secretKey string, data []byte) string {
	payloadData := publicKey + string(data) + publicKey

	keyForSign := []byte(secretKey)
	h := hmac.New(sha512.New, keyForSign)
	h.Write([]byte(payloadData))

	return base64.StdEncoding.EncodeToString([]byte(hex.EncodeToString(h.Sum(nil))))
}

func pkcs7Pad(b []byte, blockSize int) ([]byte, error) {
	if blockSize <= 0 {
		return nil, errors.New("block size less than 0")
	}
	if b == nil || len(b) == 0 {
		return nil, errors.New("empty data to encrypt")
	}
	n := blockSize - (len(b) % blockSize)
	pb := make([]byte, len(b)+n)

	copy(pb, b)
	copy(pb[len(b):], bytes.Repeat([]byte{byte(n)}, n))

	return pb, nil
}

func EncryptCBC(key, data []byte) ([]byte, error) {
	data, err := pkcs7Pad(data, aes.BlockSize)

	if err != nil {
		return nil, err
	}

	block, err := aes.NewCipher(key)

	if err != nil {
		return nil, err
	}

	cipherText := make([]byte, aes.BlockSize + len(data))
	iv := cipherText[:aes.BlockSize]
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return nil, err
	}

	mode := cipher.NewCBCEncrypter(block, iv)
	mode.CryptBlocks(cipherText[aes.BlockSize:], data)

	return cipherText, nil
}

Setup frontend SDK

The Solidgate SDK is a hosted, pre-built user interface component for payments. The SDK helps tokenize the customer’s data so that the card data does not come into contact with the merchant’s website.

When starting with the Solidgate payment form, you can use our official payment form SDK wrapper for different JS frameworks:

These integrations automatically load solid-form.js and provide a convenient interface for working with the form. Furthermore, you can use manual installation.

Alternatively, manually add the payment form SDK to your checkout page by inserting the script tag at the end of the HTML file’s <body> tag. Utilize the Solidgate CDN-hosted form for easy integration, ensuring the latest version and preventing potential issues from script modification.

1
<script src="https://cdn.solidgate.com/js/solid-form.js"></script>
warning
Check the console for a warning that Solidgate PaymentFormSdk is already initialized. If this warning appears, solid-form.js has most likely been loaded and executed twice. Remove the unnecessary connection.

Next, create a container for the payment form on your page and assign a custom ID, as shown below. Avoid setting height dimensions or display properties for elements inside the container, including the container itself, to prevent form appearance bugs due to CSS conflicts.

The following example specifies a container with the default id of Solidgate SDK.

1
<div id="solid-payment-form-container"></div>

Otherwise, you can use your own container, passing its id to iframeParams like in the example below.

1
2
3
4
5
const data = {
  iframeParams: {
    containerId: 'your-custom-container-id'
  }
}   

Form initialization

After completing all the steps described above and modifying all required parameters, you need to initiate the Solidgate SDK

1
const form = PaymentFormSdk.init(data);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import React, { FC } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
    return (<Payment 
         merchantData={props.merchantData}
         styles={props.styles}
         formParams={props.formParams}
         width={props.width}
    />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/// in app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { SolidPaymentModule } from '@solidgate/angular-sdk';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    SolidPaymentModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

/// in app.component.ts
import {Component} from '@angular/core';

import {FormType, InitConfig} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [formParams]="formParams"
      [merchantData]="merchantData"
      width="100%"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  formParams: InitConfig['formParams'] = {
    formTypeClass: FormType.Default
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
  <Payment
      :merchant-data="merchantData"
      :form-params="formParams"
      width="100%"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

const formParams: InitConfig['formParams'] = {}
</script>

Object data (or InitConfig interface in case of frameworks usage) should contain the:

chevron down chevron up
following properties

Description

The main object required to init the form. Contains all the information for creating payment on Solidgate side.

Description

Unique merchant identification. Shall be shared at the moment of registration.

Example

api_pk_7b197...ba108f842

Description

Signature of request. It allows verifying whether the request from the merchant is genuine on the payment gateway server.

Example

MjNiYjVj…ZhYmMxMzNiZDY=

Description

The encrypted aes-cbc-256 string of JSON request data with random IV (16bytes) and secret key is first 32bytes of merchant secret key.

Example

E5FKjxw5vRjjIZ….vmG2YFjg5xcvuedQ==

Description

An object that allows you to control non-mandatory parameters of the form (f.e. - Cardholder Name, templates).

Description

The parameter allows you to select the type of payment button: with continue text or default one with pay text.

Example

continue

Default

pay

Description

The text on the submit button.

Example

Pay Now

Default

Not set

Description

Defines should Cardholder field be always visible. Otherwise, it could be shown simultaneously during additional fields request.

Example

true

Default

false

Description

Mask cvv number as *** during input.

Example

true

Default

false

Description

The text on the header of the payment form.

Example

Enter your payment data

Default

Not set

Description

The text on the title of the payment form.

Example

Card info

Default

Not set

Description

Template of Solidgate payment form.

Supported templates:

  • default
  • card
  • inline
  • flat

Example

card

Default

default

Description

Visibility of the Powered by Solidgate logo. By default, is false.

Example

true

Default

false

Description

Array with list of card brands, that could display on the payment form.

Example

['verve', 'visa', 'mastercard', 'maestro', 'american-express', 'jcb', 'diners-club', 'discover', 'aura', 'elo', 'hipercard', 'cartes-bancaires']

Default

[]

Description

Array with list of secure brands, that could display on the payment form.

Example

['visa-secure', 'mcc-id-check', 'ssl', 'pci-dss', 'norton', 'mc-affee']

Default

[]

Description

Link to Google Font. Add it to be available in your styles. Please, avoid using large font sets to keep form loading fast.

Example

//fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap

Default

Not set

Description

Card form visibility. Set false to show only Google/Apple Pay buttons and status page.

Example

false

Default

true

Description

Determines, if it’s possible to submit card form using enter key press or submit button click. Usefully for implementing custom submit flow.

Example

false

Default

true

Description

Setting to disable form autofocus.

Example

false

Example

true

Description

An object that allows you to manage the styles of your payment form.

Description

Class for editing styles of all input fields on the form.

Description

Class for editing styles of all additional fields on the form.

Description

Parameter responsible for the body of the form.

Description

Card number field parameter.

Description

Expiry date field parameter.

Description

Card CVV field parameter.

Description

Cardholder parameter field.

Description

ZIP code field parameter.

Description

Submit button field parameter.

Description

The payment form title - header for the payment form.

Description

The payment form subtitle.

Description

Class for editing card template.

Example

card_view: { 'background': '#3D4251'}

Description

The error customization for card and flat template.

Description

Class for editing the size and position of card brands.

Description

An object that allows you to customize the Google Pay button.

Description

The parameter is responsible for displaying the Google Pay button on Solidgate payment form.

Example

false

Default

true

Description

The id of container to place the Google Pay button. By default, if not set, button will be displayed above the form.

Example

yourCustomContainerId

Default

Not set

Description

The color of the Google Pay button.

Supported colors:

  • default: A Google-selected default value. Currently black but it may change over time.
  • black: A black button suitable for use on white or light backgrounds.
  • white: A white button suitable for use on colorful backgrounds.

Example

white

Default

black

Description

The type of the Google Pay button.

Supported types:

  • buy
  • checkout
  • order
  • pay
  • plain
  • subscribe

Not supported types:

  • donate
  • book

Example

plain

Default

Not set

Description

The authentication method of the card transaction.

  • PAN_ONLY: This authentication method is associated with payment cards stored on file with the user’s Google Account. Returned payment data includes personal account number (PAN) with the expiration month and the expiration year.
  • CRYPTOGRAM_3DS: This authentication method is associated with cards stored as Android device tokens. Returned payment data includes a 3-D Secure (3DS) cryptogram generated on the device.

The capability to transmit only PAN_ONLY or CRYPTOGRAM_3DS is also available, and such transmission will work for both one-time payments and subscriptions.

Example

['PAN_ONLY']

Default

['PAN_ONLY', 'CRYPTOGRAM_3DS']

Description

An object that allows you to customize the Apple Pay button.

Description

The parameter is responsible for displaying the Apple Pay button.

Example

false

Default

false

Description

The id of container to place the Apple Pay button. By default, if not set, button will be displayed above the form.

Example

yourCustomContainerId

Default

Not set

Description

The color of the Apple Pay button on Solidgate payment form.

Supported colors:

  • white-outline
  • black
  • white

Example

white-outline

Default

black

Description

The type of the Apple Pay button.

Supported types:

  • check-out
  • add-money
  • buy
  • order
  • plain
  • reload
  • set-up
  • subscribe
  • top-up

Not supported types:

  • donate
  • support
  • rent
  • contribute
  • tip
  • continue
  • pay

Example

check-out

Default

plain

Description

An object that allows you to customize form container placement and sizes.

Description

The parameter allows the overriding of the form’s width. You can set the value in either percentage (e.g., 100%) or pixels (e.g., 320px).

Please note that the minimum form width is 320 pixels. This requirement is related to the 3D Secure (3DS) window provided by Visa and Mastercard, and it should be adhered to in order to ensure a secure and proper display of the form during user authentication.

Example

100%

Default

Not set

Depending on form template:

  • default: 300px
  • card: 352px
  • inline: 300px
  • flat: 320px

Description

Custom containerId to place form. If not set, for will be displayed in element with id solid-payment-form-container

Example

your-custom-container-id

Default

Not set

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const data = {
  merchantData: {
    merchant: 'api_pk_7b197...ba108f842',
    signature: 'MjliMzU4ODE3ZDVlM2E1YWZmYzI1NmU4MzU3YjhlODRkMTJmZTk1NjIxOWNiYzFmNDk0N2NkNjk5YTA5Y2Q4NzIzOWIwMTgxZTQwOGExZjFmYWQ1NzQyYjc3ZGRjMzE0MTczYTQ2OGEyMTlmNGI4YzA5ZmNhMTczZDI0ZDBkZmM=',
    paymentIntent: 'E5FKjxw5vRjjIZBKtH_Q9oN1Wmn5icMn720prO4nPB3cYpzC9wLAHwq9IwstmD-YFLFPsdq2Rk9YzRJhxdPEq2KI19fFt1QotX-smH5_xWxGfYcv9rf2Y4v4KWgbjzJylHTDM6eCXVvbdZyVU54vD3sxntN3gFiyuhEzMn8mKoDV0UdIqLN_VsTAdehBUrqk7aPNzXCfSqpy9pCBlpdFNCfgOyHoDXGGS_Z9fK3gCw7usF2v0IU96mQGzdtyEUs1Z2MJYwle7sjEkWNEb9SkpW1zUXEZCFMF8Cu-dn6fWe4cVE2Ok1MDeTE43dySgw9e8GzMxgPmG2YFjg5xcvuedQ=='
  },
  formParams: {
    buttonType: 'default',
    submitButtonText: 'Pay',
    isCardHolderVisible: true,
    hideCvvNumbers: true,
    headerText: 'Enter your debit or credit card details (from merchant)',
    titleText: 'Card info (from merchant)',
    formTypeClass: 'default',
    googleFontLink: '//fonts.googleapis.com/css2?family=DM+Sans:ital@1&display=swap',
    autoFocus: false 
  },
  styles: {
    submit_button: {
      'background-color': 'red',
      'font-size': '16px',
      'font-weight': 'bold',
      ':hover': {
        'background-color': 'green'
      },
      form_body: {
        'font-family': 'DM Sans'
      }
    }
  }
}

Form events

Using the Solidgate payment form, you can build your user actions tracking by the events that it returns.

You can subscribe to Solidgate payment events like in the examples below.

1
2
3
4
5
6
const form = PaymentFormSdk.init(data)

form.on('event_type', (e) => {
  const body = e.data // The body of any available event as it described below.
  // The code will be executed when the event is received.
})
1
2
3
4
<Payment
    {...restParams}
    onEventName={callback}
/>
1
2
3
<ngx-solid-payment
    (eventName)="callback($event)"
/>
1
2
3
<Payment
    @event-name="callback"
/>

The structure and detailed description of each event is presented below.

This event indicates that the Solidgate SDK displayed the Solidgate payment form, Google Pay, or an Apple Pay button.
1
2
3
4
interface MountedMessage {
  type: 'mounted',
  entity: 'applebtn' | 'googlebtn' | 'form' // one of listed values
}
1
2
3
form.on('mounted', e => {
  const data = e.data // MountedMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleMounted = useCallback((event: SdkMessage[MessageType.Mounted]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onMounted={handleMounted}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (mounted)="onMounted($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onMounted(event: SdkMessage[MessageType.Mounted]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @mounted="mounted"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function mounted(event: SdkMessage[MessageType.Mounted]): void {
  // here your logic
}
</script>

This event indicates that the user has successfully submitted the payment. It is triggered when valid data is entered within the form and the payment process is initiated.

The event could be triggered for one of the variations: the Solidgate payment form, Google Pay, or Apple Pay.

1
2
3
4
interface SubmitMessage {
  type: 'submit',
  entity: 'applebtn' | 'googlebtn' | 'form' // one of listed values, indicates how payment was processed
}
1
2
3
form.on('submit', e => {
  const data = e.data // SubmitMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleSubmit = useCallback((event: SdkMessage[MessageType.Submit]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onSubmit={handleSubmit}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (submit)="onSubmit($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onSubmit(event: SdkMessage[MessageType.Submit]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @submit="submit"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function submit(event: SdkMessage[MessageType.Submit]): void {
  // here your logic
}
</script>
This event indicates that the payment was successfully processed.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
interface SuccessMessage {
  type: 'success',
  entity: 'applebtn' | 'googlebtn' | 'form' // one of listed values, indicates how payment was processed
  order: { // an optional order object
    status: string // an optional order status field
    currency: string  // an optional order currency field
    amount: number  // an optional order amount field
    subscription_id: string  // an optional subscription id field
    order_id: string  // an optional order id field
  }
}
1
2
3
form.on('success', e => {
  const data = e.data // SuccessMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleSuccess = useCallback((event: SdkMessage[MessageType.Success]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onSuccess={handleSuccess}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (success)="onSuccess($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onSuccess(event: SdkMessage[MessageType.Success]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @success="success"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function success(event: SdkMessage[MessageType.Success]): void {
  // here your logic
}
</script>
This event indicates that the payment had been declined.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
interface FailMessage {
  type: 'fail'
  entity: 'applebtn' | 'googlebtn' | 'form' // one of listed values, indicates how payment was processed
  code: string // an optional error code field
  message: string // an optional error message field
  order: { // an optional order object
    status: string // an optional order status field
    currency: string  // an optional order currency field
    amount: number  // an optional order amount field
    subscription_id: string  // an optional subscription id field
    order_id: string  // an optional order id field
  }
}
1
2
3
form.on('fail', e => {
  const data = e.data // FailMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleFail = useCallback((event: SdkMessage[MessageType.Fail]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onFail={handleFail}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (fail)="onFail($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onFail(event: SdkMessage[MessageType.Fail]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @fail="fail"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function fail(event: SdkMessage[MessageType.Fail]): void {
  // here your logic
}
</script>
This event informs that the payment starts processing through the 3D flow.
1
2
3
interface VerifyMessage {
  type: 'verify'
}
1
2
3
form.on('verify', e => {
  const data = e.data // VerifyMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleVerify = useCallback((event: SdkMessage[MessageType.Verify]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onVerify={handleVerify}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (verify)="onVerify($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onVerify(event: SdkMessage[MessageType.Verify]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @verify="verify"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function verify(event: SdkMessage[MessageType.Verify]): void {
  // here your logic
}
</script>
This event informs that the iframe performs a redirect (to status or to 3d verification page).
1
2
3
interface FormRedirectMessage {
  type: 'formRedirect'
}
1
2
3
form.on('formRedirect', e => {
  const data = e.data // FormRedirectMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleRedirect = useCallback((event: SdkMessage[MessageType.Redirect]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onRedirect={handleRedirect}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (redirect)="onRedirect($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onRedirect(event: SdkMessage[MessageType.Redirect]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @redirect="redirect"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function redirect(event: SdkMessage[MessageType.Redirect]): void {
  // here your logic
}
</script>

This event information on the current state of the Solidgate payment form and the user’s interaction with the controls:

  • isTouched - external interaction with the field
  • isValid - validity check
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface InteractionMessage {
  type: 'interaction'
  target: { // Indicates source of interaction
    type: 'button' | 'input' // one of the listed
    name: 'submit' | 'googlePay' | 'applePay' | 'cardNumber' | 'cardCvv' | 'cardExpiry' | 'cardHolder' // It could be one of the listed; furthermore, Solidgate might extend the list.
    interaction: 'click' | 'change' | 'focus' | 'blur' | 'enterKeyDown' // one of the listed
  }
  cardForm: { // Indicates current card form state
    fields:  {
      cardNumber: {
        isValid: boolean
        isTouched: boolean
      }
      cardCvv: {
        isValid: boolean
        isTouched: boolean
      }
      cardExpiry: {
        isValid: boolean
        isTouched: boolean
      }
      // The rest of the fields are optional, including, but not limited to: the `cardHolder` field  
    }
    isValid: boolean
    isTouched: boolean
  }
}
1
2
3
form.on('interaction', e => {
  const data = e.data // InteractionMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleInteraction = useCallback((event: SdkMessage[MessageType.Interaction]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onInteraction={handleInteraction}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (interaction)="onInteraction($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onInteraction(event: SdkMessage[MessageType.Interaction]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @interaction="interaction"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function interaction(event: SdkMessage[MessageType.Interaction]): void {
  // here your logic
}
</script>
This event indicates that the Solidgate payment form was resized. For example, could resize after a validation message appeared.
1
2
3
4
5
interface ResizeMessage {
  type: 'resize'
  width: number
  height: number
}
1
2
3
form.on('resize', e => {
  const data = e.data // ResizeMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleResize = useCallback((event: SdkMessage[MessageType.Resize]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onResize={handleResize}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (resize)="onResize($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onResize(event: SdkMessage[MessageType.Resize]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @resize="resize"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function resize(event: SdkMessage[MessageType.Resize]): void {
  // here your logic
}
</script>
This event indicates that your styles have been applied to the Solidgate payment form. This event is helpful for cases when you want to draw your preloader over the Solidgate payment form (at this point, you may remove it).
1
2
3
interface CustomStylesAppendedMessage {
  type: 'customStylesAppended'
}
1
2
3
form.on('customStylesAppended', e => {
  const data = e.data // CustomStylesAppendedMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleCustomStylesAppended = useCallback((event: SdkMessage[MessageType.CustomStylesAppended]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onCustomStylesAppended={handleCustomStylesAppended}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (customStylesAppended)="onCustomStylesAppended($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onCustomStylesAppended(event: SdkMessage[MessageType.CustomStylesAppended]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @custom-styles-appended="customStylesAppended"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function customStylesAppended(event: SdkMessage[MessageType.CustomStylesAppended]): void {
  // here your logic
}
</script>
This event indicates that the customer has entered the card number and provides probable information about the card brand when the card number is validated. Exact details will be confirmed and relayed via webhook notification.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
interface ErrorMessage {
  type: 'error'
  value: Error
  details?: {
    code: string; // 1.01, 2.01 etc.
    message: string;
  }
}
// only included in InitPaymentError.details
interface GateError {
  code: string
  message: string
}
1
2
3
form.on('error', e => {
  const data = e.data // ErrorMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleError = useCallback((event: SdkMessage[MessageType.Error]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onError={handleError}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (error)="onError($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onError(event: SdkMessage[MessageType.Error]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @error="error"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function error(event: SdkMessage[MessageType.Error]): void {
  // here your logic
}
</script>

The following Error classes are provided:

  • ConnectionError - happens when the user experiences problems with their internet connection.
  • InitPaymentError - happens when an error with payment intent occurs during initialization. The message will contain a stringified object with code and an explanation of the particular error. Additionally, it will include a details field with the original GateError object, allowing you to create different handlers for different error codes. The following error codes are supported:
    • 1.01 - Invalid credentials or signature generated.
    • 2.01 - Invalid data in payment intent. It could be a non-existing product ID or other properties, which will be described in a message.
    • 6.01 - Something went wrong on our backed side, please contact support.
  • GatewayResponseError - occurs when we cannot parse the response from our backend. Please contact support in case of such errors.
This event indicates that the customer has entered the card number and provides information about the card brand when the card number is validated.
1
2
3
4
5
6
7
interface CardMessage {
  type: 'card'
  card: {
    brand: string // one of the card brands in upper case ('VISA', 'MASTERCARD' etc) or 'unknown'
    bin: '111222' // string with the card bin (first 6 symbols)
  }
}
1
2
3
form.on('card', e => {
  const data = e.data // CardMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleCard = useCallback((event: SdkMessage[MessageType.Card]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onCard={handleCard}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (card)="onCard($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onCard(event: SdkMessage[MessageType.Card]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @card="card"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function card(event: SdkMessage[MessageType.Card]): void {
  // here your logic
}
</script>
This event indicates that the order status was changed while processing. However, the event may not show all changes before the final order status: approved or declined.
1
2
3
4
interface OrderStatusMessage {
  type: 'orderStatus'
  response: object // partial Order status operation response (https://api-docs.solidgate.com/#tag/Card-payments/operation/Card%20order%20status)
}
1
2
3
form.on('orderStatus', e => {
  const data = e.data // OrderStatusMessage
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import React, { FC, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, SdkMessage, MessageType } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  styles?: InitConfig['styles']
  formParams?: InitConfig['formParams']
  width?: string
}> = (props) => {
  const handleOrderStatus = useCallback((event: SdkMessage[MessageType.OrderStatus]) => {
    // here logic
  }, [])
  
  return (<Payment
    {...props}
    onOrderStatus={handleOrderStatus}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {Component} from '@angular/core';

import {InitConfig, SdkMessage, MessageType} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (orderStatus)="onOrderStatus($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  onOrderStatus(event: SdkMessage[MessageType.OrderStatus]): void {
    // here your logic
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<template>
  <Payment
      :merchant-data="merchantData"
      @order-status="orderStatus"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, SdkMessage, MessageType } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function orderStatus(event: SdkMessage[MessageType.OrderStatus]): void {
  // here your logic
}
</script>

Form update

You do not have to repeatedly call the payment form when using multiple tariffs. Instead, you can request the form once and change the amount , currency , product ID , or one of the parameters of partialIntent object using the update method of the form instance.

To update Solidgate payment form parameter, generate the Signature parameter on your backend. The signature allows for verifying whether the request from the merchant is valid on the payment gateway server. It is generated from the partialIntent encrypted String

Setup backend

First of all, it is necessary to make sure that the backend is prepared, while in the example code, the formMerchantData function is called with fields:

chevron down chevron up
partialIntent object

Description

Order amount - integer without fractional component (i.e cents). For instance, 1020 means 10 USD and 20 cents.

Required, for the non-subscription workflow.

Example

1020

Description

The currency amount is represented in a three-letter currency code as per the ISO-4217 standard.

Required, for the non-subscription workflow.

Example

USD

Description

The ID of the predefined product must be passed in UUID v4 format.

Required, for the subscription workflow.

Example

faf3b86a-1fe6-4ae5-84d4-ab0651d75db2

Description

The order description in your system and for bank processing.

Example

Premium package

Description

Parameter for transaction authorization through a payment form.

Example

auth

Description

The number of payments by the customer.

Example

1

Description

Date of order creation in format YYYY-MM-DD-HH-MM-SS.

Example

2020-12-21 11:21:30

Description

Order items in UTF-8 code.

Example

item1, item2

Description

Provide this URL if you want to redirect a customer to your own Success Screen. If you do not provide the URL, Solidgate will direct customers to the Solidgate Success Screen.

Example

http://Merchant.example/success

Description

Provide this URL if you want to redirect a customer to your own Fail Screen. If you do not provide the URL, Solidgate will direct customers to the Solidgate Fail Screen.

Example

http://Merchant.example/fail

Description

Source of transactions on the merchant site.

Example

main_menu

Description

Source of traffic.

Example

facebook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "amount": 1020,
  "currency": "EUR",
  "order_description": "Premium package",
  "type": "auth",
  "order_number": "4",
  "order_date": "2022-02-21 11:21:30",
  "order_items": "item5",
  "success_url": "http://Merchant.example/success",
  "fail_url": "http://Merchant.example/fail",
  "transaction_source": "Main menu",
  "traffic_source": "Instagram"
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "product_id": "faf3b86a-1fe6-4ae5-84d4-ab0651d75db2",
  "order_description": "Premium package",
  "type": "auth",
  "order_number": "4",
  "order_date": "2022-02-21 11:21:30",
  "order_items": "item5",
  "success_url": "http://Merchant.example/success",
  "fail_url": "http://Merchant.example/fail",
  "transaction_source": "Main menu",
  "traffic_source": "Instagram"
}

Step 1 Form the partial intent data

To update, you must provide some information about the transaction. This information is encapsulated in a FormUpdateDTO object, which is created by calling the formUpdate function on your API instance.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const solidGate = require('@solidgate/node-sdk');

let api = new solidGate.Api("public_key", "secret_key");

let partialIntentData = {
	/// fill it as described in documentation
}
let formUpdateDTO = api.formUpdate(partialIntentData);

const dataToFront = formUpdateDTO.toObject()

/// This values should be applied on frontend in the following way

const form.update(dataToFront)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main

import (
	"encoding/json"
	"fmt"

	solidgate "github.com/solidgate-tech/go-sdk"
)

type UpdateParams struct {
	...
}

func main() {
	solidgateSdk := solidgate.NewSolidGateApi("public_key", "secret_key")
	partialIntent = PartialIntent{} // fill in the necessary information for updating as described in the documentation
	partialIntentBytes, err := json.Marshal(partialIntent)

	if err != nil {
		fmt.Print(err)
	}

	formUpdateDto, err := solidgateSdk.FormUpdate(partialIntentBytes)

	if err != nil {
		fmt.Print(err)
	}

	// ...	
}
1
2
3
4
5
6
7
<?php

use SolidGate\API\Api;

$api = new Api('public_key', 'secret_key');

$formUpdateDTO = $api->formUpdate(['JSON payment intent // fill as described in documentation']);
1
2
3
4
5
6
7
from solidgate import ApiClient

client = ApiClient("public_key", "secret_key")

responseDTO = client.form_update({
    partial_intent_dict  // fill as described in documentation
})
1
2
3
4
5
6
7
val api = Api(HttpClient(), Credentials("public_key", "secret_key"))

val attributes = Attributes(mapOf(
	// fill as described in documentation
))

val formUpdateDTO = api.formUpdate(attributes)

Step 2 Pass the generated data to your frontend

The FormUpdateDTO object that is returned by the formUpdateDTO function is an instance of a class, so you may need to convert it to a plain object before you can use it in your front-end code. In the example code, this is done by calling the toObject function on the FormUpdateDTO object, which returns a plain JavaScript object.

Once you have formed the merchant data and converted it to a plain object, you can use it in your front-end code to update with partialIntent encrypted String

Partial form update

chevron down chevron up
Update method parameters

Description

The encrypted aes-cbc-256 string of JSON request data with random IV (16bytes) and secret key is the first 32bytes of Merchant secret key.

Example

E5FKjxw5vRjjIZ....vmG2YFjg5xcvuedQ==

Description

Signature of request. It allows verifying whether the request from the Merchant is genuine on the payment gateway server.

Example

MjNiYjVj…ZhYmMxMzNiZDY=

1
2
3
4
form
  .update({ partialIntent, signature })
  .then(callbackForSuccessUpdate)
  .catch(callbackForFailedUpdate);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import React, { FC, useRef, useCallback, useEffect } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, ClientSdkInstance } from "@solidgate/react-sdk"

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
  update?: {
    partialIntent: string;
    signature: string;
  }
}> = (props) => {
  const formResolve = useRef<(form: ClientSdkInstance) => void>(() => {})
  const formPromise = useRef<Promise<ClientSdkInstance>>(new Promise(resolve => {
    formResolve.current = resolve
  }))

  const handleOnReadyPaymentInstance = useCallback((form: ClientSdkInstance) => {
    formResolve.current(form)
  }, [])
  
  useEffect(() => {
    if (props.update)  {
      formPromise.then(() => form
        .update(props.update)
        .then(callbackForSuccessUpdate)
        .catch(callbackForFailedUpdate)
      )
    }
  }, [props.update])
  
  return (
    <Payment
      merchantData={props.merchantData}
      onReadyPaymentInstance={handleOnReadyPaymentInstance}
  />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import {Component} from '@angular/core';
import {BehaviorSubject, filter} from 'rxjs'
import {InitConfig, SdkMessage, MessageType} from '@solidgate/angular-sdk';

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (readyPaymentInstance)="formSubject$.next($event)"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  formSubject$ = new BehaviorSubject<ClientSdkInstance | null>(null)

  form$ = this.formSubject$.pipe(filter(Boolean))
  
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  update(payload: {
    partialIntent: string;
    signature: string;
  }): void {
    this.form$.subscribe(form => form
      .update(payload)
      .then(callbackForSuccessUpdate)
      .catch(callbackForFailedUpdate))
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
  <Payment
      :merchant-data="merchantData"
      @ready-payment-instance="onReadyPaymentInstance"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig, ClientSdkInstance } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

function onReadyPaymentInstance(form: ClientSdkInstance): void {
  form
      .update({ partialIntent, signature })
      .then(callbackForSuccessUpdate)
      .catch(callbackForFailedUpdate)
}
</script>
It is important to note that you must handle possible errors, including network errors, in callbackForFailedUpdate by calling a valid update or init; otherwise, the form will remain unresponsive.

If one of the parameters in the updateIntent request is invalid (e.g. the product_id will not be unique), you will get an error.

1
2
3
4
5
6
7
8
{
  "error": {
    "code": "2.01",
    "message": [
      "Invalid Data"
    ]
  }
}

Coupons

Solidgate provides the ability to apply discounts to subscription products through two schemas:

  • Predefined coupon application flow
    In this flow, the coupon ID is embedded and encrypted in the paymentIntent during payment initialization. Once the form is initialized, the applied discount will already be present.
  • Direct coupon application flow
    In this flow, the coupon code is applied after the payment form has been initialized using a special applyCoupon method.

Predefined coupon flow

If you want to apply a discount during form initialization, you can include the coupon_id parameter in the encryption of the paymentIntent, and then call form.init

Description

ID of the coupon which corresponds to the specific product discount, must be passed in UUID v4 format.

The coupon flow will only be activated when a product_id is supplied of the subscription workflow.

Without a product_id, the coupon_id will be disregarded.

Example

eb4c6e93-4c53-447a-b215-5d5786af9844

After a successful form initialization, the discount will already be applied. However, in the case of an invalid or expired coupon, you will receive an error event with a GateError when calling form.init

Direct coupon flow

If you have already initialized the payment form and wish to apply a discount to it, you can do so by calling the applyCoupon method with the specified couponCode string.

1
2
3
4
form
  .applyCoupon("exampleCoupon")
  .then((result: ApplyCouponPrices) => { /* success handlers here */ })
  .catch((error: ApplyCouponError) => { /* error handlers here */ })

If the coupon is valid and was successfully applied, applyCoupon will resolve with ApplyCouponPrices object with schema:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
interface ApplyCouponPrices {
  productPrice: {  // initial product price
    amount: string;
    currency: string;
    currencyIcon: string;
  };
  discountPrice: { // product price with applied discount
    amount: string;
    currency: string;
    currencyIcon: string;
  };
  trialPrice?: {
    amount: string;
    currency: string;
    currencyIcon: string;
  };
}
If the trial price is present, the user will be charged at this rate. The discountPrice may be applied in future payments as per the rules set up in the HUB. You can use data from ApplyCouponPrices to provide users with insights into the original product price and the discounted price.

In the event that the coupon application is unsuccessful due to reasons such as an expired coupon code or other issues, the applyCoupon method will reject with an ApplyCouponError, which contains details of the error with a specific code and message within the GateError interface.

ApplyCouponError.details will contain original GateError with a specific code and message

1
2
3
4
5
6
7
8
interface ApplyCouponError extends Error {
  details?: GateError;
}

interface GateError {
  code: string
  message: string
}

Custom submission

The Solidgate payment form has two options for submitting a payment, submit via:

  • a click on the payment button
  • the form.submit method

We leave the option to display your payment button below the payment form. Use this feature to collect additional data from the user.

To hide the payment form submit button, you need to set the allowSubmit display property in formParams to false during initialization. This will not only hide the button but also prevent the form from being submitted via enter key press in form fields.

1
2
3
4
5
6
7
const form = PaymentFormSdk.init({
  ...restData,
  formParams: {
    ...restFormParamsIfPresent,
    allowSubmit: false
  }
})
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import React, { FC } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, ClientSdkInstance } from "@solidgate/react-sdk"

const formParams = {
  allowSubmit: false
}

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
}> = (props) => {
  return (
    <Payment
      merchantData={props.merchantData}
      formParams={formParams}
    />)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import {Component} from '@angular/core';

import {InitConfig} from "@solidgate/angular-sdk";

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [formParams]="formParams"
      [merchantData]="merchantData"
      width="100%"
    ></ngx-solid-payment>
  `
})
export class AppComponent {
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  formParams: InitConfig['formParams'] = {
    allowSubmit: false
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
  <Payment
      :merchant-data="merchantData"
      :form-params="formParams"
      width="100%"
  />
</template>

<script lang="ts" setup>
import { defineAsyncComponent } from 'vue'
import { InitConfig } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

const formParams: InitConfig['formParams'] = {
  allowSubmit: false
}
</script>

To submit the payment form without using a Solidgate button, you need to call the form’s submit method.

1
document.getElementById('yourCustomSubmitButtonId').addEventListener('click', () => form.submit())
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import React, { FC, useRef, useCallback } from 'react'
import ReactDOM from 'react-dom';
import Payment, { InitConfig, ClientSdkInstance } from "@solidgate/react-sdk"

const formParams = {
  allowSubmit: false
}

export const MyPayment: FC<{
  merchantData: InitConfig['merchantData']
}> = (props) => {
  const [isMounted, setIsMounted] = useState(false);
  const [form, setForm] = useState<ClientSdkInstance | null>(null);
  
  const handleOnReadyPaymentInstance = useCallback((form: ClientSdkInstance) => {
    setForm(form)
  }, [])
  
  const handleMounted = useCallback(() => {
    setIsMounted(true)
  }, [])

  return (
    <div>
        <Payment
          merchantData={props.merchantData}
          formParams={formParams}
          onReadyPaymentInstance={handleOnReadyPaymentInstance}
          onMounted={handleMounted}
        />
      {mounted && (
        <button type="button" onClick={() => {
          form?.submit()
        }}>
          {"Submit"}
        </button>
      )}
    </div>
  )
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import {Component} from '@angular/core';
import {BehaviorSubject, filter} from 'rxjs'
import {InitConfig, SdkMessage, MessageType} from '@solidgate/angular-sdk';

@Component({
  selector: 'app-root',
  template: `
    <ngx-solid-payment
      [merchantData]="merchantData"
      (mounted)="mounted = true"
      (readyPaymentInstance)="formSubject$.next($event)"
    ></ngx-solid-payment>
    <button *ngIf="mounted" type="button" (click)="submit()"></button>
  `
})
export class AppComponent {
  isMounted = false;
  
  formSubject$ = new BehaviorSubject<ClientSdkInstance | null>(null)
  
  merchantData: InitConfig['merchantData'] = {
    merchant: '<<--YOUR MERCHANT ID-->>',
    signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
    paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
  }

  private form$ = this.formSubject$.pipe(filter(Boolean))

  submit(): void {
    this.form$.subscribe(form => form.submit())
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<template>
  <Payment
      :merchant-data="merchantData"
      @mounted="onMounted"
      @ready-payment-instance="onReadyPaymentInstance"
  />
  <button     
      v-if="mounted"
      @click="submit">
    Submit
  </button>
</template>

<script lang="ts" setup>
import { defineAsyncComponent, ref } from 'vue'
import { InitConfig, ClientSdkInstance } from '@solidgate/vue-sdk'
const Payment = defineAsyncComponent(() => import('@solidgate/vue-sdk'))

const merchantData: InitConfig['merchantData'] = {
  merchant: '<<--YOUR MERCHANT ID-->>',
  signature: '<<--YOUR SIGNATURE OF THE REQUEST-->>',
  paymentIntent: '<<--YOUR PAYMENT INTENT-->>'
}

let mounted = ref(false)

let formResolve: (form: ClientSdkInstance) => {} = () => {} 
const formPromise = new Promise<ClientSdkInstance>(resolve => {
  formResolve = resolve
})

function onReadyPaymentInstance(form: ClientSdkInstance): void {
  formResolve(form)
}

function onMounted(): void {
  mounted.value = true
}

function submit(): void {
  formPromise.then(form => form.submit())
}
</script>
Actual submit will not happen if some of the following conditions are met:

  • additional fields are requested to be displayed: user will see validation error on appeared field
  • some fields on the form have yet to be validated: user will see validation errors on form
  • validation errors are present in the form fields

Otherwise, the form will be submitted.

Additional fields

Solidgate payment form will check the Card BIN and receive a list of necessary additional fields according to information about the BIN country (the first 6 digits).

Also, depending on the provider, the customer phone parameter is often used to verify the identity of the person making a payment; for example, in India, this is indian_customer_phone . This parameter typically requires the person to enter their registered mobile phone number, which is then used to authenticate the payment.

chevron down chevron up
Additional fields

  • Country Argentina
  • Country Code (ISO 3166-1) ARG
  • Field Title DNI

  • Country Bangladesh
  • Country Code (ISO 3166-1) BGD
  • Field Title National identity card

  • Country Bolivia
  • Country Code (ISO 3166-1) BOL
  • Field Title Cedula de Identidad

  • Country Brazil
  • Country Code (ISO 3166-1) BRA
  • Field Title CPF

  • Country Cameroon
  • Country Code (ISO 3166-1) CMR
  • Field Title CNI

  • Country Chile
  • Country Code (ISO 3166-1) CHL
  • Field Title Rol Único Tributario

  • Country China
  • Country Code (ISO 3166-1) CHN
  • Field Title Citizen ID Number

  • Country Colombia
  • Country Code (ISO 3166-1) COL
  • Field Title Cedula de Ciudadania

  • Country Costa Rica
  • Country Code (ISO 3166-1) CRI
  • Field Title Cédula de Identidad

  • Country Dominican Republic
  • Country Code (ISO 3166-1) DOM
  • Field Title Identity card

  • Country Ecuador
  • Country Code (ISO 3166-1) ECU
  • Field Title Cédula de Identidad

  • Country El Salvador
  • Country Code (ISO 3166-1) SLV
  • Field Title Personal Identification Card

  • Country Egypt
  • Country Code (ISO 3166-1) EGY
  • Field Title Identity card

  • Country Ghana
  • Country Code (ISO 3166-1) GHA
  • Field Title Ghana Card

  • Country Guatemala
  • Country Code (ISO 3166-1) GTM
  • Field Title CUI

  • Country India
  • Country Code (ISO 3166-1) IND
  • Field Title PAN

  • Country India
  • Country Code (ISO 3166-1) IND
  • Field Title Customer Phone

  • Country Indonesia
  • Country Code (ISO 3166-1) IDN
  • Field Title NIK

  • Country Japan
  • Country Code (ISO 3166-1) JPN
  • Field Title My Number

  • Country Kenya
  • Country Code (ISO 3166-1) KEN
  • Field Title National ID Card

  • Country Malaysia
  • Country Code (ISO 3166-1) MYS
  • Field Title NRIC

  • Country Mexico
  • Country Code (ISO 3166-1) MEX
  • Field Title CURP

  • Country Morocco
  • Country Code (ISO 3166-1) MAR
  • Field Title CNIE

  • Country Nigeria
  • Country Code (ISO 3166-1) NGA
  • Field Title NIN

  • Country Panama
  • Country Code (ISO 3166-1) PAN
  • Field Title Cedula de Identidad

  • Country Paraguay
  • Country Code (ISO 3166-1) PRY
  • Field Title Cédula de Identidad

  • Country Peru
  • Country Code (ISO 3166-1) PER
  • Field Title DNI

  • Country Philippines
  • Country Code (ISO 3166-1) PHL
  • Field Title PSN

  • Country Senegal
  • Country Code (ISO 3166-1) SEN
  • Field Title CNI or ECOWAS ID Card

  • Country South Africa
  • Country Code (ISO 3166-1) ZAF
  • Field Title South African Identity Card

  • Country Tanzania
  • Country Code (ISO 3166-1) TZA
  • Field Title National Identity Card

  • Country Thailand
  • Country Code (ISO 3166-1) THA
  • Field Title Thai Identity Card

  • Country Turkey
  • Country Code (ISO 3166-1) TUR
  • Field Title T.C. Kimlik No.

  • Country Uganda
  • Country Code (ISO 3166-1) UGA
  • Field Title National ID number (NIC)

  • Country Uruguay
  • Country Code (ISO 3166-1) URY
  • Field Title Cédula de Identidad

  • Country Vietnam
  • Country Code (ISO 3166-1) VNM
  • Field Title VNID

  • Country United States
  • Country Code (ISO 3166-1) USA
  • Field Title ZIP code

Additional fields classes will be formed as follows:

1
    "class": "input_group zip_code additional_field"

You can customize all additional fields at once using the additional_field class. In this case, styles will be applied to all additional field classes described in the table above.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PaymentFormSdk.init({
  ...restData,
  styles: {
    'additional_field': {
      'input': {
        'color': 'red'
      }
    }
  }
})

If you want to customize a specific field, you need to apply styles to this specific additional field class name.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PaymentFormSdk.init({
  ...restData,
  styles: {
    'guatemala_cui': {
      'input': {
        'color': 'red'
      }
    }
  }
})

Validation rules

Front-end validation and auto-tabulation prevent errors and fraud, verify data correctness, enhance user experience, end increase transaction success.

Validation of form fields occurs when a field loses focus.

Card number

  • Validate the correctness of data entered (check data entered for validity)

The validity of the card number is verified by the Luhn Algorithm. The Luhn Algorithm calculates the check digits of a plastic card number in accordance with the standard ISO/IEC 7812 WIKI

  • Define card brand to display the desired logo

For card payments, one of the most important UX rules is automatic card type detection and automatic card number formatting (spacing). To implement these functions, you need to know the IIN ranges and spacing patterns for card types.

  • Determine the country of the card by BIN and add fields dynamically if necessary

To dynamically add fields to the form, we need to define the country of the card brand. Depending on this, we add the required field on the frontend.

Expiry date

  • The expiration date field accepts dates in both of the following formats: MM/YY, MM/YYYY
  • The date entered should be in the future

CVV

The CVV field can only accept 3 or 4 digits. Validation of the CVV field depends on the card brand:

  • for AMERICAN EXPRESS, the CVV field must contain 4 digits
  • for all other card brands, the CVV field must contain 3 digits

Cardholder

The field with the name of the cardholder is disabled by default. It is possible to enable this field through CSS styles.

  • Rules for the field
    • at least 3 characters
    • convert from Cyrillic to Latin
    • must not contain symbols and numbers, only letters
    • auto tabulation is disabled

Supported browsers

The Solidgate payment form requires that the customer's browser supports TLS 1.2. If TLS 1.2 is not supported, the payment form will not be displayed. Additionally, it is important to know:

  • some of the user’s extensions can break the correct behavior of our payment form
  • we don’t guarantee payment form stable functioning when rendered inside in-app browsers (Facebook, Instagram browser, etc.)

The Solidgate payment form (JS) strives to support the latest versions of all major browsers. For security reasons and to provide customization options to customers, we do not support browsers that do not receive security updates and are low usage.

Our support extends to the following browsers:

Only the three most recent major versions are supported for all browsers.

Supported translations

The Solidgate payment form is translated automatically by detecting the location of the customer’s browser.

  • Afrikaans af
  • Arabic ar
  • Bengali bn
  • Chinese zh
  • Czech cs
  • Danish da
  • Dutch nl
  • English en
  • Finnish fi
  • French fr
  • German de
  • Hindi hi
  • Indonesian id
  • Italian it
  • Japanese ja
  • Korean ko
  • Malay ms
  • Norwegian no
  • Polish pl
  • Portuguese pt
  • Romanian ro
  • Russian ru
  • Spanish es
  • Swedish sv
  • Thai th
  • Turkish tr
  • Ukrainian uk
  • Vietnamese vi

You can also configure localization with the following subset of IETF language tags WIKI by passing in into PaymentIntent object


Related articles FAQ

Payment form 1-st payment flow
How-to initiate 2-step payment via Payment form (Auth+Settle)
The Payment form is not loading
Using Java for Payment form