Resign payment form
Get started
Sign In
Resign payment form
Efficiently integrate a resign payment form with saved card details

Solidgate’s introduction of a Resign Form marks a significant advancement in payment processing, offering clients the convenience of one-click payments by securely utilizing stored card details.

This is especially beneficial for returning customers, as it allows the reuse of card information, significantly streamlining the payment process. After a customer’s initial transaction, their card details are securely saved. For future purchases, these details are quickly accessible, enabling effortless one-click transactions.

This efficient approach not only saves time but also eliminates the common hassle of repeatedly entering payment information, thus enhancing the shopping experience and potentially boosting conversion rates.

It offers dynamic adaptation to card information, supports multiple languages, and is compatible with secure browser versions.

Here’s how the process unfolds:

  1. Initial payment
    The customer makes the Guide
    This guide simplifies the process of adding the Solidgate Payment Form to your website. It covers the preparation of the backend, SDK installation, API instance creation, and merchant data setup.
    first
    payment.
  2. Token storage
    Solidgate tokenizes card data and returns a secure recurring token that you store.
  3. Recognition of regular customers
    You identify your regular customers on subsequent visits and suggest paying with a previous payment method.
  4. Resign Form initialization
    You can initialize our Resign Form with the recurring token you stored.
  5. New payment completed
    The customer fills out the Resign Form only with the CVV field.

Setup backend

Begin by ensuring that the backend is adequately prepared. In the provided example code, the function formMerchantData is called with the necessary fields.

Solidgate SDK includes an SDK method that requires a resign intent payload. This payload is similar to the payment intent but also includes a token field for the tokenized PAN number.

 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
{
  "order_id": "123456",
  "recurring_token": "7ats8da7sd8-a66dfa7-a9s9das89t",
  "amount": 1020,
  "currency": "USD",
  "order_description": "Premium package",
  "order_items": "item1, item2",
  "order_date": "2020-12-21 11:21:30",
  "order_number": 1,
  "type": "auth",
  "settle_interval": 48,
  "retry_attempt": 1,
  "force3ds": true,
  "customer_date_of_birth": "2000-11-21",
  "customer_email": "test@solidgate.com",
  "customer_first_name": "John",
  "customer_last_name": "Snow",
  "customer_phone": "380111111111",    
  "ip_address": "8.8.8.8",
  "traffic_source": "Instagram",
  "transaction_source": "main_menu",
  "purchase_country": "CHN",    
  "geo_country": "GBR",
  "geo_city": "New Castle",
  "billing_address": {
    "address": "Street 3D, Apartment 343",
    "country": "United States",
    "state": "Delaware",
    "city": "New Castle",
    "zip_code": "03127"
  },
  "language": "en",
  "website": "http://google.com",
  "device": "iPhone 8 iOS 12.0",
  "platform": "WEB",
  "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (HTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
  "order_metadata": {
    "coupon_code": "NY2018",
    "partner_id": "123989"
  },
  "success_url": "http://merchant.example/success",
  "fail_url": "http://merchant.example/fail"
}
 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
{
  "order_id": "123456",
  "recurring_token": "7ats8da7sd8-a66dfa7-a9s9das89t",
  "product_price_id": "faf3b86a-1fe6-4ae5-84d4-ab0651d75db2",
  "coupon_id": "eb4c6e93-4c53-447a-b215-5d5786af9844",
  "customer_account_id": "4dad42f808",
  "currency": "USD",
  "order_description": "Premium package",
  "order_items": "item1, item2",
  "order_date": "2020-12-21 11:21:30",
  "order_number": 1,
  "type": "auth",
  "settle_interval": 48,
  "retry_attempt": 1,
  "force3ds": true,
  "customer_date_of_birth": "2000-11-21",
  "customer_email": "test@solidgate.com",
  "customer_first_name": "John",
  "customer_last_name": "Snow",
  "customer_phone": "380111111111",
  "ip_address": "8.8.8.8", 
  "traffic_source": "Instagram",
  "transaction_source": "main_menu",
  "purchase_country": "CHN",
  "geo_country": "GBR",
  "geo_city": "New Castle",
  "billing_address": {
    "address": "Street 3D, Apartment 343",
    "country": "United States",
    "state": "Delaware",
    "city": "New Castle",
    "zip_code": "03127"
  },
  "language": "en",
  "website": "http://google.com",
  "device": "iPhone 8 iOS 12.0",
  "platform": "WEB",
  "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (HTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36",
  "order_metadata": {
    "coupon_code": "NY2018",
    "partner_id": "123989"
  },
  "success_url": "http://merchant.example/success",
  "fail_url": "http://merchant.example/fail"
}

Additionally, when setting up the resignIntent object for the resign process, an extra parameter recurring_token is sent.

Step 1 Form the resign intent data

Start by generating the resign intent data, incorporating the previously obtained payment token. This is a crucial step in preparing for the transaction.

  1. Invoke the formMerchantData function within your API instance.
  2. Ensure to include the recurring_token in the resignIntent fields.

Step 2 Pass the generated data to your frontend

  • Pass the encrypted resignIntent string to your front end.
    This is typically done during the form initialization phase.

This action creates the FormInitDTO object, which is pivotal for the charge creation. The recurring_token is instrumental in associating this new transaction with the payment method used previously.

Resign form initialization

After completing all necessary steps and adjusting the required parameters for the Resign Form, you can initiate the Solidgate SDK in a manner similar to the regular payment setup, but tailored for the resign process.

To create Resign Form, you need to call the PaymentFormSdk.resign(resignRequest: ResignRequest, formConfig?: ResignFormConfig) method from the PaymentFormSdk.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const setupResignPaymentForm = async () => {
  try {
    const form = await PaymentFormSdk.resign(resignRequest, formConfig);
    
    // Now you can call payment form methods such as form.on, form.submit etc...
  } catch (error) {
    // Error will be thrown if payment form initialization fails.
    // You can handle it here.
  }
};
 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
import { Resign, ResignFormConfig, ResignRequest, ClientSdkInstance } from '@solidgate/react-sdk'

function CheckoutPage() {
  const resignRequest: ResignRequest = {
    merchant: '<--YOUR DATA-->',
    signature: '<--YOUR DATA-->',
    resignIntent: '<--YOUR DATA-->'
  }

  const appearance: ResignFormConfig["appearance"] = {
    submitButtonText: "Pay",
    allowSubmit: true,
    resignCvvLabel: "CVV",
    resignCvvPlaceholder: "123",
    hideCvvNumbers: true
  }

  const container: ResignFormConfig["container"] = {
    width: "500px"
  }

  const styles: ResignFormConfig["styles"] = {
    "resign-submit-button": {
      'background-color': 'green',
      'font-size': '16px',
      'font-weight': 'bold',
      ':hover': {
        'background-color': 'green'
      },
    }
  }

  const handleInitFailed = (error: Error) => {
    // you can handle init failure here
  }

  const handleReadyResignInstance = (formInstance: ClientSdkInstance) => {
    // you can receive ClientSDKInstance here to perform additional actions such as manual form submission, form updates, etc.
  }

  const handleSuccess = () => {
    // you can handle successful payment here
    // complete list of the available events can be found in the 'Form Events' section of this documentation
  }

  return (
    <Resign
      resignRequest={resignRequest}
      appearance={appearance}
      container={container}
      styles={styles}
      onReadyResignInstance={handleReadyResignInstance}
      onResignInitFailed={handleInitFailed}
      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
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
//app.component.ts
import { Component } from '@angular/core';
import { ClientSdkInstance, ResignFormConfig, ResignRequest, SolidResignModule } from '@solidgate/angular-sdk'

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [SolidResignModule],
  template: `
    <ngx-solid-resign
      [resignRequest]="resignRequest"
      [appearance]="appearance"
      [container]="container"
      [styles]="styles"
      (readyResignInstance)="handleReadyResignInstance($event)"
      (resignInitFailed)="handleInitFailed($event)"
      (success)="handleSuccess()"
    ></ngx-solid-resign>
  `
})
export class AppComponent {
  resignRequest: ResignRequest = {
    merchant: '<--YOUR DATA-->',
    signature: '<--YOUR DATA-->',
    resignIntent: '<--YOUR DATA-->',
  }

  appearance: ResignFormConfig["appearance"] = {
    submitButtonText: "Pay",
    allowSubmit: true,
    resignCvvLabel: "CVV",
    resignCvvPlaceholder: "123",
    hideCvvNumbers: true
  }

  container: ResignFormConfig["container"] = {
    width: "500px"
  }

  styles: ResignFormConfig["styles"] = {
    "resign-submit-button": {
      'background-color': 'green',
      'font-size': '16px',
      'font-weight': 'bold',
      ':hover': {
        'background-color': 'green'
      },
    }
  }

  resignFormConfig: ResignFormConfig = {
    appearance: {
      submitButtonText: "Pay",
      allowSubmit: true,
      googleFontLink: "https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap",
      resignCvvLabel: "CVV",
      resignCvvPlaceholder: "123",
      hideCvvNumbers: true
    },
    container: {
      width: "500px"
    },
  }

  handleReadyResignInstance(formInstance: ClientSdkInstance) {
    // you can receive ClientSDKInstance here to perform additional actions such as manual form submission, form updates, etc.
  }

  handleInitFailed(error: Error) {
    // you can handle init failure here
  }

  handleSuccess() {
    // you can handle successful payment here
    // complete list of the available events can be found in the 'Form Events' section of this documentation
  }
}
 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
<script setup lang="ts">
import { Resign, ResignRequest, ResignFormConfig, ClientSdkInstance } from "@solidgate/vue-sdk";

const resignRequest: ResignRequest = {
  merchant: '<--YOUR DATA-->',
  signature: '<--YOUR DATA-->',
  resignIntent: '<--YOUR DATA-->',
}

const appearance: ResignFormConfig["appearance"] = {
  submitButtonText: "Pay",
  allowSubmit: true,
  resignCvvLabel: "CVV",
  resignCvvPlaceholder: "123",
  hideCvvNumbers: true
}

const container: ResignFormConfig["container"] = {
  width: "500px"
}

const styles: ResignFormConfig["styles"] = {
  "resign-submit-button": {
    'background-color': 'green',
    'font-size': '16px',
    'font-weight': 'bold',
    ':hover': {
      'background-color': 'green'
    },
  }
}

function handleReadyResignInstance(formInstance: ClientSdkInstance) {
  // you can receive ClientSDKInstance here to perform additional actions such as manual form submission, form updates, etc.
}

function handleInitFailed(error: Error) {
  // you can handle init failure here
}

function handleSuccess() {
  // you can handle successful payment here
  // complete list of the available events can be found in the 'Form Events' section of this documentation
}

</script>

<template>
  <Resign
      :resign-request="resignRequest"
      :appearance="appearance"
      :container="container"
      :styles="styles"
      @readyResignInstance="handleReadyResignInstance"
      @resignInitFailed="handleInitFailed"
      @success="handleSuccess"
  />
</template>

The resignRequest: ResignRequest object contains all the necessary information for the resign initialization.

It is required and should contain the:

1
2
3
4
5
const resignRequest = {
  merchant: 'api_pk_7b197...ba108f842',
  signature: 'MjliMzU4ODE3ZDVlM2E1YWZmYzI1NmU4MzU3YjhlODRkMTJmZTk1NjIxOWNiYzFmNDk0N2NkNjk5YTA5Y2Q4NzIzOWIwMTgxZTQwOGExZjFmYWQ1NzQyYjc3ZGRjMzE0MTczYTQ2OGEyMTlmNGI4YzA5ZmNhMTczZDI0ZDBkZmM=',
  resignIntent: 'E5FKjxw5vRjjIZBKtH_Q9oN1Wmn5icMn720prO4nPB3cYpzC9wLAHwq9IwstmD-YFLFPsdq2Rk9YzRJhxdPEq2KI19fFt1QotX-smH5_xWxGfYcv9rf2Y4v4KWgbjzJylHTDM6eCXVvbdZyVU54vD3sxntN3gFiyuhEzMn8mKoDV0UdIqLN_VsTAdehBUrqk7aPNzXCfSqpy9pCBlpdFNCfgOyHoDXGGS_Z9fK3gCw7usF2v0IU96mQGzdtyEUs1Z2MJYwle7sjEkWNEb9SkpW1zUXEZCFMF8Cu-dn6fWe4cVE2Ok1MDeTE43dySgw9e8GzMxgPmG2YFjg5xcvuedQ=='
}

The formConfig: ResignFormConfig object allows you to customize the resign form.

It is optional and can contain the:

 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
const formConfig = {
  container: {
    id: "resign-form-iframe",
    width: "700px"
  },
  appearance: {
    autoFocus: false,
    submitButtonText: "Buy",
    allowSubmit: true,
    googleFontLink: "https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@200&display=swap",
    resignCvvLabel: "CVV",
    resignCvvPlaceholder: "CVV",
    hideCvvNumbers: true
  },
  styles: {
    "resign-input-group": {
      ".valid": {
        "input": {
          "background-color": "#e2ffe8"
        }
      },
      ".error": {
        "input": {
          "background-color": "#ff8686"
        }
      }
    }
  }
}

In the case of failed initialization, you will receive an error with the following schema:

1
interface InitResignError extends Error {}

Customization

To tailor your resignation form, implement custom styles within ResignFormConfig.styles. This is done by supplying an object-like structure, where each top-level key corresponds to a form element’s classname, and its value comprises an object with specific styling rules.

The value can include:

  • classnames, like .error or .not-empty, with each holding a distinct styles object.
  • CSS selectors, for instance, .error > input, also each possessing a unique styles object.
  • direct CSS style rule names along with their respective values, such as "color": "purple".

This structure ensures a coherent and logical approach to customizing the resignation form, providing flexibility in styling while maintaining technical accuracy.

The complete list of permitted top-level classnames is provided above in the ResignFormConfig section.

Note that unknown top-level classnames will be ignored. Refer to the supported list in the ResignFormConfig section for valid classnames.

Be aware that all CSS rules, selectors, and classnames nested within top-level classnames will not undergo validation.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const formConfig = {
  styles: {
    "resign-input-group": { // top-level classname for an form elements
      ".valid": { // 
        "input": {
          "background-color": "#e2ffe8"
        }
      },
      ".error": {
        "input": { // more fine-grain styling with nesting
          "background-color": "#ff8686"
        }
      }
    },
    "resign-submit-button": {
      "background-color": "#5b7742"
    },
    "resign-cvv": {
      " input::placeholder": { // pseudo-class selectors
        "color": "#000"
      }
    }
  }
}

UI flow

A specific parameter to control the UI flow (column or inline) is not provided within ResignFormConfig.

However, the UI flow can be manipulated via the ResignFormConfig.styles object. For instance, setting "flex-direction": "row" for the resign-form-content element alters the default column layout, but this can be counterbalanced by styling additional form elements to achieve the desired appearance.

For those seeking immediate application with minimal customization, two default styling options are available for both column and inline layouts.

The column layout is embedded in the build. To make the form look inline, please include styles from the section below to your ResignFormConfig.styles object.

By default, we provide the most mobile-friendly form layout variant - the column layout - which is also suitable for desktop integrations.

Nothing else is needed.

If you want to set the CVV label to be visible (it is hidden by default), you can add the following styles to your ResignFormConfig.styles

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const formConfig = {
  styles: {
    "resign-label": {
      "display": "block"
    },
    "resign-input-block": {
      "flex-direction": "row-reverse",
      "align-items": "center"
    }
  }
}
If you want to make inline form, add the following styles to your ResignFormConfig.styles object:
 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
const formConfig = {
  styles: {
    "resign-form-content": {
      "padding": "1em 0.75em",
      "background-color": "#f5f5f5",
      "border-radius": "6px",
      "align-items": "center",
      "flex-direction": "row"
    },
    "resign-input-group": {
      "margin": "0",
      "flex": "1"
    },
    "resign-card-preview": {
      "margin": "0"
    },
    "resign-label": {
      "display": "block"
    },
    "resign-input-block": {
      "flex-direction": "row-reverse",
      "flex-wrap": "wrap",
      "align-items": "center",
      "input": {
        "width": "auto"
      }
    }
  }
}
Note that the optimal width for the inline form starts from 500px; it’s better to set this size or higher inside ResignFormConfig.container.width.

Limitations

  • The complete list of allowed top-level classnames is available in the ResignFormConfig section. Unknown top-level classnames will be ignored.
  • CSS rules, selectors, and classnames nested within top-level classnames are not subject to validation.
  • The ResignFormConfig does not inherently control the UI flow (column or inline display). However, you can adjust the UI flow through the ResignFormConfig.styles object.
  • The default column layout is mobile-friendly and suitable for desktops. For an inline layout, additional styles must be added to the ResignFormConfig.styles object.
  • The resignation form currently does not support PaymentFormSdk.update and PaymentFormSdk.applyCoupon methods. Attempts to use these will result in errors captured by form.on("error", (err) => { ... }).

Error insights

These insights help merchants understand common issues and optimize their strategies for successful resign transactions, enhancing customer experience and potentially boosting conversion rates.

Top errors for successful resigns:

  • Errors like Guide
    “Invalid data” code message is used for validation errors, with the reason for the validation triggering specified in the body (object error) of the response.
    2.01
    (Invalid Data) and Guide
    The card issuer bank blocked the card for payments.
    3.01
    (Card is Blocked) are common and relate to incorrect card data entry.
  • Errors Guide
    3DS URL was not displayed to the cardholder during 3D Secure authentication attempts.
    2.10
    (Invalid 3DS Flow on Merchant Side), Guide
    The user went through a payment flow, but the bank did not initiate 3DS authorization.
    2.11
    (Invalid 3DS Flow on Bank Side), and Guide
    Indicates an authentication failure during the 3D Secure process; advise the customer to retry the transaction and check for potential fraud.
    5.01
    (3D Secure Verification Failed) pertain to issues with 3D Secure authentication.

Enhanced success rate in resigns:

  • Resigns are frequently successful following a Guide
    The customer’s card balance has insufficient funds.
    3.02
    (Insufficient Funds) error.
  • Errors like Guide
    The card has been declined for an unknown reason.
    3.08
    (Do Not Honor) and Guide
    The issuing bank blocked the transaction due to possible fraud.
    3.10
    (Suspected Fraud) often lead to successful resigns as well.

Looking for help? Contact us
Stay informed with Changelog