[
{
"title":"Testing",
"link":"https://docs.solidgate.com/payments/testing/",
"text":"Simulate payments to test your integration before launching in production.",
"imgSrc":"https://solidgate.com/wp-content/uploads/2022/06/icon-customizable.svg"
}
,
{
"title":"Create your payment form",
"link":"https://docs.solidgate.com/payments/integrate/payment-form/create-your-payment-form/",
"text":"Understand how to integrate the payment form into your product.",
"imgSrc":"https://solidgate.com/wp-content/uploads/2022/06/icon-payments.svg"
}
,
{
"title":"Subscriptions",
"link":"https://docs.solidgate.com/subscriptions/",
"text":"Create and maintain a stable and healthy business subscription model.",
"imgSrc":"https://solidgate.com/wp-content/uploads/2022/06/icon-global.svg"
}
]
This guide simplifies the process of adding the Payment Form to your website. It covers the preparation of the back end, SDK installation, API instance creation, and merchant data setup. Furthermore, it outlines the initialization of the form using various JavaScript frameworks and how to customize its appearance through parameters and styles.
Back end setup
Begin by setting up your back end, a crucial step for successful implementation. Use the Solidgate SDK to integrate the Payment Form seamlessly into your platforms. This SDK offers intuitive features for transactions and payment form customization. To initiate a charge, supply transaction-specific information through paymentIntent fields.
paymentIntent object
Expand all
Description
Order ID, which must be unique, is specified in the merchant system.
Example
123456
Description
Identifier of the predefined product must be passed in UUID v4 format.
One of product_id or product_price_id is required for subscription workflow.
Order amount - integer without fractional component (i.e. cents). For instance, 1020 means 10 USD and 20 cents.
However, if the type is auth, amount can be 0, for zero-amount flow. For type as charge, an amount of 0 triggers an error.
Required, for one-time payment workflows.
Example
1020
Description
Currency amount is represented in a three-letter currency code as per the ISO-4217 standard.
Required, for one-time payment workflow.
Example
USD
Description
Order description in your system and for bank processing.
To improve the clarity of payment processing, it is advised to keep the description brief, ideally not exceeding 100 characters
Example
Premium package
Description
Order items in UTF-8 code.
Example
item1, item2
Description
Date of order creation in format YYYY-MM-DD-HH-MM-SS.
Example
2020-12-21 11:21:30
Description
Number of payments by the customer.
Example
1
Description
Process this payment as an authorization auth or charge charge.
It is mandatory to select auth for authorization. Should it not be specified, charge automatically becomes the default type.
For the two-step or auth+settle payment flow, with the auth parameter include settle_interval in hours.
Each payment is authorized upon initiation, and then authorized funds are settled after the time interval specified in the settle_interval parameter.
Example
auth
Description
Delay applied before transaction settlement indicates the hours to wait before settling and should be provided together with type:auth. The maximum value:
for Visa customer-initiated payments: 240 hours = 10 days
for Visa merchant-initiated payments: 120 hours = 5 days
for all other card brands: 144 hours = 6 days
Example
48
Description
Number of retry payment.
Example
1
Description
Routing payments flag for 3DS flow (enabled by Solidgate account manager).
Example
true
Description
Merchant ID parameter you receive on Google’s side.
Required for displaying the Google Pay button.
Example
10911390523550288022
Description
Merchant name, which can be displayed to the customers when paying via Google.
It would be better to pass this parameter so that Google does not substitute it on its own.
Example
Solidgate
Description
Merchant name, which can be displayed to the customers when paying via Apple.
Example
Test
Description
Customer birthdate in format YYYY-MM-DD.
Example
2000-11-21
Description
Customer email.
If not provided, it is collected on the payment form.
For PayPal, an autogenerated email may initialize the order, which user enters while logging into their PayPal account.
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
Source of traffic.
Example
facebook
Description
Source of transactions on the merchant site.
Example
main_menu
Description
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.
If this parameter is not provided, it will be automatically inferred from the header.
Example
WEB
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
Metadata is useful for storing additional, structured information about an object, consisting of up to 10 key-value pairs with a validation limit of 380 characters per field.
The callback notification returns an order_metadata from the order in each state.
Example
“coupon_code”: “NY2018", “partner_id”: “123989"
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.
To interact with the Solidgate API, create an API instance by calling the API constructor function, passing your Public public_key and Secret secret_key keys as arguments.
To create a charge, you must provide transaction-related information. This information is contained in a FormInitDTO object, which is created by invoking the formMerchantData function on your API instance. In the example code, this function is called with the paymentIntent fields.
1
2
3
4
5
6
7
<?phpuseSolidGate\API\Api;$api=newApi('public_key','secret_key');$response=$api->formMerchantData(['JSON payment intent // fill as described in documentation']);
1
2
3
4
5
6
7
8
9
10
constsolidGate=require('@solidgate/node-sdk');letapi=newsolidGate.Api("public_key","private_key");letpaymentIntentData={/// fill it as described in documentation
}letmerchantData=api.formMerchantData(paymentIntentData);constdataToFront=merchantData.toObject()
packagemainimport("encoding/json""fmt"solidgate"github.com/solidgate-tech/go-sdk")funcmain(){solidgateSdk:=NewSolidGateApi("public_key","secret_key")paymentIntent=PaymentIntent{}// fill as described in documentation
paymentIntentBytes,err:=json.Marshal(paymentIntent)iferr!=nil{fmt.Print(err)}formInitDto,err:=solidgateSdk.FormMerchantData(paymentIntentBytes)iferr!=nil{fmt.Print(err)}// ...
}
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
An alternative option for integrating the payment form exists without utilizing the Solidgate SDK.
Back end preparation Set up server-side code to facilitate communication with the Solidgate API, using your preferred programming language and libraries.
Create DTO Create a JSON object that includes the required fields for a payment transaction and encrypt it.
Generate merchant data After successfully encrypting the paymentIntent, pass it to your front-end code for further processing, such as form initialization.
Signature generation To integrate the
Guide
Learn to authenticate API requests and fix validation errors effectively.
signature parameter
process with the encryption steps for initializing form, the flow for paymentIntent encrypted String
User action: convert data The user initiates a transaction, providing the necessary payment data.
Token generation: generate initialization vector (IV) Internally, a secure random IV is created, corresponding to the required size for the encryption process.
Key preparation: create encryption key The system extracts the needed size from the provided secret key and converts it into the appropriate format for encryption.
Encryption setup: initialize cipher A cipher object is established using the selected encryption algorithm, mode, and padding. The cipher is then initialized in encryption mode with the key and IV.
Data processing: encrypt data The input data, now in the form of a JSON string, is converted to bytes. The initialized cipher is used to encrypt this data.
Integration step: combine IV and encrypted data The IV and the encrypted data are combined into a single-byte array, integrating the necessary components for secure transmission.
*There are specific nuances to consider to ensure compatibility and security, such as using the pycryptodome library for Python 3 environments.
Encoding for transmission: Base64 encoding This combined data (IV and encrypted data) is encoded into a Base64 string, preparing it for safe transmission over the network.
<?phpclassPaymentIntentGenerator{privatestring$secretKey;publicfunction__construct(string$secretKey){$this->secretKey=$secretKey;}privatefunctiongenerateEncryptedFormData(array$attributes):string{$attributes=json_encode($attributes);$secretKey=substr($this->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$this->base64UrlEncode($iv.$encrypt);}privatefunctionbase64UrlEncode($data):string{returnstr_replace(['+','/'],['-','_'],base64_encode($data));}publicfunctiontestGenerateEncryptedFormData():void{$attributes=["order_id"=>"order_id","amount"=>1100,"currency"=>"USD","order_description"=>"description","customer_email"=>"test@yourdomain.com","ip_address"=>"8.8.8.8","platform"=>"WEB",];$encryptedFormData=$this->generateEncryptedFormData($attributes);echo"Encrypted Form Data: ".$encryptedFormData.PHP_EOL;}}$yourClassInstance=newPaymentIntentGenerator("api_sk_xxxxaxxxxbdf47a2aea17eb3xxxxxxxx");$yourClassInstance->testGenerateEncryptedFormData();
The
Solidgate
SDK
provides a pre-built user interface component for payments. It assists in tokenizing customer data, ensuring that card information never interacts with the merchant’s website.
When starting with the Payment Form, you can use our official payment form SDK wrapper for different JavaScript frameworks:
These integrations automatically load solid-form.js and offer a convenient interface for form operation. 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.
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 it a custom ID, as demonstrated below. Avoid setting height or display properties for elements inside the container, including the container itself, to prevent form appearance issues due to CSS conflicts.
The following example specifies a container with the default id of Solidgate SDK.
1
<divid="solid-payment-form-container"></div>
Alternatively, use your own container, passing its id to iframeParams as shown in the example below.
<template><Payment:merchant-data="merchantData":form-params="formParams"width="100%"/></template><scriptlang="ts"setup>import{defineAsyncComponent}from'vue'import{InitConfig}from'@solidgate/vue-sdk'constPayment=defineAsyncComponent(()=>import('@solidgate/vue-sdk'))constmerchantData:InitConfig['merchantData']={merchant:'<<--YOUR MERCHANT ID-->>',signature:'<<--YOUR SIGNATURE OF THE REQUEST-->>',paymentIntent:'<<--YOUR PAYMENT INTENT-->>'}constformParams:InitConfig['formParams']={}</script>
This class targets all input fields within the form, enabling you to apply consistent styling.
To view changes, directly modify the input_group class in your CSS. Activation occurs automatically as the form renders.
Defines the style for the payment form’s header.
Adjustments to the header class become visible upon form load and are particularly useful for aligning with your brand identity.
Responsible for the overall container of the form, allowing for adjustments in font, color, or spacing.
The form_body becomes visible when the form is initialized and can be tailored to fit seamlessly within your site’s design.
Customize the subtitle of your payment form, enhancing readability and focus.
Changes are immediately visible, providing a quick way to align form instructions with user expectations.
Controls the styling of the form’s submit button.
To hide the button, set the display property to none in your styles. This class becomes crucial when you prefer a custom button or need to adhere to specific design systems.
Wraps fields like CVV and Expiry Date in the default form template, enabling a two-column layout for a compact and organized look.
Alterations to this class are seen as soon as the form is rendered.
Edit the card template, such as changing the background color with a property like card_view: { 'background': '#3D4251'}.
This class is particularly impactful for branding purposes and user engagement.
Modifies the display of card brand logos, ensuring they fit well within your form’s design.
The size and position can be adjusted to meet visual design standards.
Specific to the card number input field, this class can be styled to indicate valid input or errors, with immediate feedback enhancing the user’s experience.
Targets the CVV field, allowing for distinct styles during error states or focus, providing immediate visual cues to the user.
Controls the appearance of the expiry date field.
Customizing this field can ensure consistency with other form elements and can trigger when the field is in focus or an error state.
Description
Defines the style for the cardholder’s name field, which is a crucial element for transactions.
A string parameter ranging from 3 to 50 characters. The pattern ^[a-zA-Z]+ [a-zA-Z]+(?: [a-zA-Z]+)*$ is used to validate the format.
The field specifies the name as it appears on the card, essential for transaction processing. It requires at least one space between the first and last names to ensure accuracy and enhance transaction conversions.
Manages the styling of any additional fields that may be required for specific transactions, ensuring these fields are visible and styled according to the form’s design when they become relevant.
Styling for the ZIP code field can be crucial for forms requiring address information, and adjustments to this class will be seen as soon as the ZIP code field is rendered.
Customize the error messages associated with the card and flat templates, ensuring that any validation errors are communicated effectively and clearly.
The errors customization for card and flat template.
Edits the appearance of security-related branding, such as SSL certificates or payment compliance logos, reinforcing trust and security on the payment form.
Description
Customize the Google Pay button.
Description
Displays the Google Pay button.
Example
false
Default
true
Description
Identifier of container to place the Google Pay button.
By default, if not set, button will be displayed above the form.
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
Customize the Apple Pay button.
Description
Displays the Apple Pay button.
Example
false
Default
true
Description
Defines the type of Apple Pay button integration.
In non-Safari browsers, Apple Pay can only be displayed when using the js integration type.
Example
js
Default
css
Description
Identifier 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
Color of the Apple Pay button.
Supported colors:
white-outline
black
white
Example
white-outline
Default
black
Description
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
Customizes form container placement and sizes.
Description
Displays the PayPal button.
If you do not pass this field with true, the PayPal button will be hidden.
Example
true
Default
false
Description
Identifier of the container where the PayPal button will be placed.
Button adapts to the size of its container element.
Description
Customize form container placement and sizes.
Description
Parameter allows the overriding of the form 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 320px. 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
Verify that the ip_address added matches the selected region if using a VPN.
Ensure that the form styles do not have the opacity property set to 0.
Inspect form styles for any elements that could be covering the form area.
Ensure that you generate a new order_id for each transaction attempt.
You can test payments to make sure everything works as expected. If the outlined steps do not resolve the issue, please contact the Solidgate support team for further assistance. When contacting, share the details of the issue and the steps you have taken to resolve it.
Form update
There is no need to call the payment form repeatedly when using multiple tariffs. Request the form once and modify the
amount
,
currency
,
product ID
, or any parameter of the
partialIntent
object using the form instance’s
update
method.
To update a Payment Form parameter, generate the
Guide
Learn to authenticate API requests and fix validation errors effectively.
signature parameter
on your back end. This signature verifies the merchant’s request authenticity on the payment gateway server and originates from the
partialIntent encrypted String
Back end setup
Firstly, ensure that the back end is prepared. In the example code, the
formMerchantData
function is called with fields.
Specifically, this method permits updates only to a predefined list of fields, distinct from those available during initial form creation in the paymentIntent object, updates are confined to select parameters within the partialIntent object.
It is important to note that attempting to update fields not defined in the allowed list will result in an
error
response.
partialIntent object
Expand all
Description
Identifier of the predefined product must be passed in UUID v4 format.
One of product_id or product_price_id is required for subscription workflow.
One of product_id or product_price_id is required for subscription workflow.
Example
faf3b86a-1fe6-4ae5-84d4-ab0651d75db2
Description
Order amount - integer without fractional component (i.e. cents). For instance, 1020 means 10 USD and 20 cents.
However, if the type is auth, amount can be 0, for zero-amount flow. For type as charge, an amount of 0 triggers an error.
Required, for one-time payment workflow.
Example
1020
Description
Currency amount is represented in a three-letter currency code as per the ISO-4217 standard.
Required, for one-time payment workflow.
Example
USD
Description
Order description in your system and for bank processing.
To improve the clarity of payment processing, it is advised to keep the description brief, ideally not exceeding 100 characters
Example
Premium package
Description
Order items in UTF-8 code.
Example
item1, item2
Description
Date of order creation in format YYYY-MM-DD-HH-MM-SS.
Example
2020-12-21 11:21:30
Description
Number of payments by the customer.
Example
1
Description
Process this payment as an authorization auth or charge charge.
Example
auth
Description
Source of traffic.
Example
facebook
Description
Source of transactions on the merchant site.
Example
main_menu
Description
Metadata is useful for storing additional, structured information about an object, consisting of up to 10 key-value pairs with a validation limit of 380 characters per field.
The callback notification returns an order_metadata from the order in each state.
Example
“coupon_code”: “NY2018", “partner_id”: “123989"
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.
For updating, provide transaction-related information. This information resides in a FormUpdateDTO object, created by invoking the formUpdate function on your API instance.
1
2
3
4
5
6
7
<?phpuseSolidGate\API\Api;$api=newApi('public_key','secret_key');$formUpdateDTO=$api->formUpdate(['JSON payment intent // fill as described in documentation']);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
constsolidGate=require('@solidgate/node-sdk');letapi=newsolidGate.Api("public_key","secret_key");letpartialIntentData={/// fill it as described in documentation
}letformUpdateDTO=api.formUpdate(partialIntentData);constdataToFront=formUpdateDTO.toObject()/// This values should be applied on front end in the following way
constform.update(dataToFront)
packagemainimport("encoding/json""fmt"solidgate"github.com/solidgate-tech/go-sdk")typeUpdateParamsstruct{...}funcmain(){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)iferr!=nil{fmt.Print(err)}formUpdateDto,err:=solidgateSdk.FormUpdate(partialIntentBytes)iferr!=nil{fmt.Print(err)}// ...
}
1
2
3
4
5
6
7
valapi=Api(HttpClient(),Credentials("public_key","secret_key"))valattributes=Attributes(mapOf(// fill as described in documentation
))valformUpdateDTO=api.formUpdate(attributes)
The
FormUpdateDTO
object, returned by the
formUpdateDTO
function, is a class instance. Convert it to a plain object for use in front-end code. This conversion is accomplished by calling the
toObject
function on the
FormUpdateDTO
object, resulting in a plain JavaScript object.
After forming the merchant data and converting it to a plain object, use it in front-end code to update with the partialIntent encrypted String
Partial form update
Update method parameters
Expand all
Description
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.
<template><Payment:merchant-data="merchantData"@ready-payment-instance="onReadyPaymentInstance"/></template><scriptlang="ts"setup>import{defineAsyncComponent}from'vue'import{InitConfig,ClientSdkInstance}from'@solidgate/vue-sdk'constPayment=defineAsyncComponent(()=>import('@solidgate/vue-sdk'))constmerchantData:InitConfig['merchantData']={merchant:'<<--YOUR MERCHANT ID-->>',signature:'<<--YOUR SIGNATURE OF THE REQUEST-->>',paymentIntent:'<<--YOUR PAYMENT INTENT-->>'}functiononReadyPaymentInstance(form:ClientSdkInstance):void{form.update({partialIntent,signature}).then(callbackForSuccessUpdate).catch(callbackForFailedUpdate)}</script>
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>
`})exportclassAppComponent{formSubject$=newBehaviorSubject<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))}}
It is very important to handle possible errors, including network errors, in callbackForFailedUpdate
by calling a valid update or init; otherwise, the form will remain unresponsive.
If an invalid parameter exists in the updateIntent request (e.g., a non-unique product_id), an error occurs.
Solidgate provides the ability to apply discounts to subscription products through two schemas:
Predefined coupon 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 flow In this flow, the coupon code is applied after the payment form has been initialized using a special applyCoupon method.
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 InitPaymentError 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:
If a trial price exists, users are charged at this rate. Future payments may also have the discountPrice applied based on rules established in the HUB. Utilize data from ApplyCouponPrices to inform users about the original and discounted product prices.
In cases where the coupon application fails due to reasons like an expired coupon code, applyCoupon rejects with an ApplyCouponError, containing error details with a specific code and message within error.details