EmbeddedMethod UI

Learn how to use the EmbeddedMethod UI embedded component to add the ability to securely store a payment profile or execute a sale
Applies to:Developers

Use the EmbeddedMethod component to capture a payment method or make a sale using any payment method. This is the most flexible and customizable component Payabli offers to developers.


This component is supported in the Playground. Use the Embedded Component Playground to edit and design embedded components in real time, and export the code to use in your own site or app.

Usage

This section shows how to use the EmbeddedMethod UI component in your project. Use the interactive demo to see how the component works, then follow the configuration walkthrough to set it up in your project.

See Library URLs for important information about embedded components library URLs.

Interactive demo

This demo shows the component in action with transaction processing and visual feedback. When the component processes a transaction, the demo displays the JSON response.

Embedded content from https://files.buildwithfern.com/payabli.docs.buildwithfern.com/2025-08-18T20:36:28.788Z/snippets/demos/embedded-method.html

EmbeddedMethod UI Demo

Loading content...

Configuration walkthrough

The interactive walkthrough displays code examples alongside step-by-step explanations.

Loading walkthrough content

Loading walkthrough...

Loading walkthrough...

/// Include the Payabli Script

First, include the Payabli embedded component script in your HTML. This loads the core PayabliComponent class that powers all embedded components. Including <meta charset="UTF-8"> in the <head> element prevents problems with special characters such as ‘á’ or ‘ñ’.

1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="UTF-8">
5 <title>Payabli Integration</title>
6</head>
7<body>
8 <script src="https://embedded-component-sandbox.payabli.com/component.js" data-test></script>
9</body>
10</html>

/// Create the Container and Tab Structure

Add a container element where the embedded component will render. The id attribute becomes the rootContainer in your configuration. Create tabs to switch between card and ACH payment methods.

-18
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="UTF-8">
5 <title>Payabli Integration</title>
6</head>
7<body>
8 <h1>Payment Form</h1>
9 <div class="payment-container">
10 <div class="tabs">
11 <button class="tab active" data-method="card">Payment Card</button>
12 <button class="tab" data-method="ach">Bank Debit</button>
13 </div>
14 <div class="form-content">
15 <div id="pay-component-1"></div>
16 <button id="submit-btn" class="hidden">Process Payment</button>
17 </div>
18 </div>
19
20 <script src="https://embedded-component-sandbox.payabli.com/component.js" data-test></script>
21</body>
22</html>

/// Add Basic Styling

Add CSS styles for the tabs to handle active and focus states.

-52
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="UTF-8">
5 <title>Payabli Integration</title>
6 <style>
7 .tabs {
8 display: flex;
9 border-bottom: 1px solid #e5e5e5;
10 margin-bottom: 20px;
11 }
12
13 .tab {
14 flex: 1;
15 padding: 16px 24px;
16 text-align: center;
17 cursor: pointer;
18 background: white;
19 border: none;
20 border-bottom: 2px solid transparent;
21 transition: all 0.2s ease;
22 }
23
24 .tab:hover {
25 color: #333;
26 background: #f8f9fa;
27 }
28
29 .tab.active {
30 color: #007bff;
31 border-bottom-color: #007bff;
32 }
33
34 .hidden {
35 display: none;
36 }
37
38 #submit-btn {
39 background: #4f46e5;
40 color: white;
41 padding: 12px 24px;
42 border: none;
43 border-radius: 6px;
44 cursor: pointer;
45 margin-top: 16px;
46 }
47
48 #submit-btn:disabled {
49 background: #9ca3af;
50 cursor: not-allowed;
51 }
52 </style>
53</head>
54<body>
55 <h1>Payment Form</h1>
56 <div class="payment-container">
57 <div class="tabs">
58 <button class="tab active" data-method="card">Payment Card</button>
59 <button class="tab" data-method="ach">Bank Debit</button>
60 </div>
61 <div class="form-content">
62 <div id="pay-component-1"></div>
63 <button id="submit-btn" class="hidden">Process Payment</button>
64 </div>
65 </div>
66
67 <script src="https://embedded-component-sandbox.payabli.com/component.js" data-test></script>
68</body>
69</html>

/// Configure Card Payment Method

Create the configuration object for card payments. The token must be a public API token.

-158
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="UTF-8">
5 <title>Payabli Integration</title>
6 <style>
7 .tabs {
8 display: flex;
9 border-bottom: 1px solid #e5e5e5;
10 margin-bottom: 20px;
11 }
12
13 .tab {
14 flex: 1;
15 padding: 16px 24px;
16 text-align: center;
17 cursor: pointer;
18 background: white;
19 border: none;
20 border-bottom: 2px solid transparent;
21 transition: all 0.2s ease;
22 }
23
24 .tab:hover {
25 color: #333;
26 background: #f8f9fa;
27 }
28
29 .tab.active {
30 color: #007bff;
31 border-bottom-color: #007bff;
32 }
33
34 .hidden {
35 display: none;
36 }
37
38 #submit-btn {
39 background: #4f46e5;
40 color: white;
41 padding: 12px 24px;
42 border: none;
43 border-radius: 6px;
44 cursor: pointer;
45 margin-top: 16px;
46 }
47
48 #submit-btn:disabled {
49 background: #9ca3af;
50 cursor: not-allowed;
51 }
52 </style>
53</head>
54<body>
55 <h1>Payment Form</h1>
56 <div class="payment-container">
57 <div class="tabs">
58 <button class="tab active" data-method="card">Payment Card</button>
59 <button class="tab" data-method="ach">Bank Debit</button>
60 </div>
61 <div class="form-content">
62 <div id="pay-component-1"></div>
63 <button id="submit-btn" class="hidden">Process Payment</button>
64 </div>
65 </div>
66
67 <script src="https://embedded-component-sandbox.payabli.com/component.js" data-test></script>
68 <script>
69 let payComponent;
70
71 const cardConfig = {
72 type: "methodEmbedded",
73 rootContainer: "pay-component-1",
74 token: "your-public-api-token",
75 entryPoint: "your-entry-point",
76 defaultOpen: "card",
77 temporaryToken: false,
78 card: {
79 enabled: true,
80 amex: true,
81 discover: true,
82 visa: true,
83 mastercard: true,
84 jcb: true,
85 diners: true,
86 inputs: {
87 cardHolderName: {
88 label: "NAME ON CARD",
89 size: 12,
90 row: 0,
91 order: 0
92 },
93 cardNumber: {
94 label: "CARD NUMBER",
95 size: 6,
96 row: 1,
97 order: 0
98 },
99 cardExpirationDate: {
100 label: "EXPIRATION",
101 size: 6,
102 row: 1,
103 order: 1
104 },
105 cardCvv: {
106 label: "CVV",
107 size: 6,
108 row: 2,
109 order: 0
110 },
111 cardZipcode: {
112 label: "ZIP CODE",
113 size: 6,
114 row: 2,
115 order: 1
116 }
117 }
118 },
119 functionCallBackSuccess: function (response) {
120 // This callback covers both 2XX and 4XX responses
121 console.log(response);
122 switch (response.responseText) {
123 case "Success":
124 // Tokenization was successful
125 alert(`Success: ${response.responseData.resultText}`);
126 break;
127 case "Declined":
128 // Tokenization failed due to processor decline or validation errors
129 // Recommend reinitialization of the component so that the user can try again
130 // with different card data
131 alert(`Declined: ${response.responseData.resultText}`);
132 payComponent.payabliExec("reinit");
133 break;
134 default:
135 // Other response text. These are normally errors with Payabli internal validations
136 // before processor engagement
137 // We recommend reinitializing the component.
138 // If the problem persists, contact Payabli to help debug
139 alert(`Error: ${response.responseText}`);
140 payComponent.payabliExec("reinit");
141 break;
142 }
143 },
144 functionCallBackError: function(errors) {
145 console.log("Payment error:", errors);
146 alert("Payment processing error occurred");
147 payComponent.payabliExec("reinit");
148 },
149 functionCallBackReady: function(data) {
150 const btn = document.getElementById("submit-btn");
151 if (data[1] === true) {
152 btn.classList.remove("hidden");
153 } else {
154 btn.classList.add("hidden");
155 }
156 }
157 };
158 </script>
159</body>
160</html>

/// Configure ACH Payment Method

Create the configuration object for ACH payments. The token must be a public API token.

-242
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="UTF-8">
5 <title>Payabli Integration</title>
6 <style>
7 .tabs {
8 display: flex;
9 border-bottom: 1px solid #e5e5e5;
10 margin-bottom: 20px;
11 }
12
13 .tab {
14 flex: 1;
15 padding: 16px 24px;
16 text-align: center;
17 cursor: pointer;
18 background: white;
19 border: none;
20 border-bottom: 2px solid transparent;
21 transition: all 0.2s ease;
22 }
23
24 .tab:hover {
25 color: #333;
26 background: #f8f9fa;
27 }
28
29 .tab.active {
30 color: #007bff;
31 border-bottom-color: #007bff;
32 }
33
34 .hidden {
35 display: none;
36 }
37
38 #submit-btn {
39 background: #4f46e5;
40 color: white;
41 padding: 12px 24px;
42 border: none;
43 border-radius: 6px;
44 cursor: pointer;
45 margin-top: 16px;
46 }
47
48 #submit-btn:disabled {
49 background: #9ca3af;
50 cursor: not-allowed;
51 }
52 </style>
53</head>
54<body>
55 <h1>Payment Form</h1>
56 <div class="payment-container">
57 <div class="tabs">
58 <button class="tab active" data-method="card">Payment Card</button>
59 <button class="tab" data-method="ach">Bank Debit</button>
60 </div>
61 <div class="form-content">
62 <div id="pay-component-1"></div>
63 <button id="submit-btn" class="hidden">Process Payment</button>
64 </div>
65 </div>
66
67 <script src="https://embedded-component-sandbox.payabli.com/component.js" data-test></script>
68 <script>
69 let payComponent;
70
71 const cardConfig = {
72 type: "methodEmbedded",
73 rootContainer: "pay-component-1",
74 token: "your-public-api-token",
75 entryPoint: "your-entry-point",
76 defaultOpen: "card",
77 temporaryToken: false,
78 card: {
79 enabled: true,
80 amex: true,
81 discover: true,
82 visa: true,
83 mastercard: true,
84 jcb: true,
85 diners: true,
86 inputs: {
87 cardHolderName: {
88 label: "NAME ON CARD",
89 size: 12,
90 row: 0,
91 order: 0
92 },
93 cardNumber: {
94 label: "CARD NUMBER",
95 size: 6,
96 row: 1,
97 order: 0
98 },
99 cardExpirationDate: {
100 label: "EXPIRATION",
101 size: 6,
102 row: 1,
103 order: 1
104 },
105 cardCvv: {
106 label: "CVV",
107 size: 6,
108 row: 2,
109 order: 0
110 },
111 cardZipcode: {
112 label: "ZIP CODE",
113 size: 6,
114 row: 2,
115 order: 1
116 }
117 }
118 },
119 functionCallBackSuccess: function (response) {
120 // This callback covers both 2XX and 4XX responses
121 console.log(response);
122 switch (response.responseText) {
123 case "Success":
124 // Tokenization was successful
125 alert(`Success: ${response.responseData.resultText}`);
126 break;
127 case "Declined":
128 // Tokenization failed due to processor decline or validation errors
129 // Recommend reinitialization of the component so that the user can try again
130 // with different card data
131 alert(`Declined: ${response.responseData.resultText}`);
132 payComponent.payabliExec("reinit");
133 break;
134 default:
135 // Other response text. These are normally errors with Payabli internal validations
136 // before processor engagement
137 // We recommend reinitializing the component.
138 // If the problem persists, contact Payabli to help debug
139 alert(`Error: ${response.responseText}`);
140 payComponent.payabliExec("reinit");
141 break;
142 }
143 },
144 functionCallBackError: function(errors) {
145 console.log("Payment error:", errors);
146 alert("Payment processing error occurred");
147 payComponent.payabliExec("reinit");
148 },
149 functionCallBackReady: function(data) {
150 const btn = document.getElementById("submit-btn");
151 if (data[1] === true) {
152 btn.classList.remove("hidden");
153 } else {
154 btn.classList.add("hidden");
155 }
156 }
157 };
158
159 const achConfig = {
160 type: "methodEmbedded",
161 rootContainer: "pay-component-1",
162 token: "your-public-api-token",
163 entryPoint: "your-entry-point",
164 defaultOpen: "ach",
165 temporaryToken: false,
166 ach: {
167 enabled: true,
168 checking: true,
169 savings: true,
170 inputs: {
171 achAccountHolderName: {
172 label: "ACCOUNT HOLDER NAME",
173 placeholder: "Account Holder Name",
174 floating: false,
175 size: 6,
176 row: 0,
177 order: 0
178 },
179 achRouting: {
180 label: "ROUTING NUMBER",
181 placeholder: "123456789",
182 floating: false,
183 size: 6,
184 row: 1,
185 order: 0
186 },
187 achAccount: {
188 label: "ACCOUNT NUMBER",
189 placeholder: "Account Number",
190 floating: false,
191 size: 6,
192 row: 1,
193 order: 1
194 },
195 achAccountType: {
196 label: "ACCOUNT TYPE",
197 floating: false,
198 size: 6,
199 row: 0,
200 order: 1
201 }
202 }
203 },
204 functionCallBackSuccess: function (response) {
205 // This callback covers both 2XX and 4XX responses
206 console.log(response);
207 switch (response.responseText) {
208 case "Success":
209 // Tokenization was successful
210 alert(`Success: ${response.responseData.resultText}`);
211 break;
212 case "Declined":
213 // Tokenization failed due to processor decline or validation errors
214 // Recommend reinitialization of the component so that the user can try again
215 // with different card data
216 alert(`Declined: ${response.responseData.resultText}`);
217 payComponent.payabliExec("reinit");
218 break;
219 default:
220 // Other response text. These are normally errors with Payabli internal validations
221 // before processor engagement
222 // We recommend reinitializing the component.
223 // If the problem persists, contact Payabli to help debug
224 alert(`Error: ${response.responseText}`);
225 payComponent.payabliExec("reinit");
226 break;
227 }
228 },
229 functionCallBackError: function(errors) {
230 console.log("Payment error:", errors);
231 alert("Payment processing error occurred");
232 payComponent.payabliExec("reinit");
233 },
234 functionCallBackReady: function(data) {
235 const btn = document.getElementById("submit-btn");
236 if (data[1] === true) {
237 btn.classList.remove("hidden");
238 } else {
239 btn.classList.add("hidden");
240 }
241 }
242 };
243 </script>
244</body>
245</html>

/// Add Tab Switching Logic

Add JavaScript code for the tabs. The code handles reinitializing the component when users change payment methods.

-260
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="UTF-8">
5 <title>Payabli Integration</title>
6 <style>
7 .tabs {
8 display: flex;
9 border-bottom: 1px solid #e5e5e5;
10 margin-bottom: 20px;
11 }
12
13 .tab {
14 flex: 1;
15 padding: 16px 24px;
16 text-align: center;
17 cursor: pointer;
18 background: white;
19 border: none;
20 border-bottom: 2px solid transparent;
21 transition: all 0.2s ease;
22 }
23
24 .tab:hover {
25 color: #333;
26 background: #f8f9fa;
27 }
28
29 .tab.active {
30 color: #007bff;
31 border-bottom-color: #007bff;
32 }
33
34 .hidden {
35 display: none;
36 }
37
38 #submit-btn {
39 background: #4f46e5;
40 color: white;
41 padding: 12px 24px;
42 border: none;
43 border-radius: 6px;
44 cursor: pointer;
45 margin-top: 16px;
46 }
47
48 #submit-btn:disabled {
49 background: #9ca3af;
50 cursor: not-allowed;
51 }
52 </style>
53</head>
54<body>
55 <h1>Payment Form</h1>
56 <div class="payment-container">
57 <div class="tabs">
58 <button class="tab active" data-method="card">Payment Card</button>
59 <button class="tab" data-method="ach">Bank Debit</button>
60 </div>
61 <div class="form-content">
62 <div id="pay-component-1"></div>
63 <button id="submit-btn" class="hidden">Process Payment</button>
64 </div>
65 </div>
66
67 <script src="https://embedded-component-sandbox.payabli.com/component.js" data-test></script>
68 <script>
69 let payComponent;
70
71 const cardConfig = {
72 type: "methodEmbedded",
73 rootContainer: "pay-component-1",
74 token: "your-public-api-token",
75 entryPoint: "your-entry-point",
76 defaultOpen: "card",
77 temporaryToken: false,
78 card: {
79 enabled: true,
80 amex: true,
81 discover: true,
82 visa: true,
83 mastercard: true,
84 jcb: true,
85 diners: true,
86 inputs: {
87 cardHolderName: {
88 label: "NAME ON CARD",
89 size: 12,
90 row: 0,
91 order: 0
92 },
93 cardNumber: {
94 label: "CARD NUMBER",
95 size: 6,
96 row: 1,
97 order: 0
98 },
99 cardExpirationDate: {
100 label: "EXPIRATION",
101 size: 6,
102 row: 1,
103 order: 1
104 },
105 cardCvv: {
106 label: "CVV",
107 size: 6,
108 row: 2,
109 order: 0
110 },
111 cardZipcode: {
112 label: "ZIP CODE",
113 size: 6,
114 row: 2,
115 order: 1
116 }
117 }
118 },
119 functionCallBackSuccess: function (response) {
120 // This callback covers both 2XX and 4XX responses
121 console.log(response);
122 switch (response.responseText) {
123 case "Success":
124 // Tokenization was successful
125 alert(`Success: ${response.responseData.resultText}`);
126 break;
127 case "Declined":
128 // Tokenization failed due to processor decline or validation errors
129 // Recommend reinitialization of the component so that the user can try again
130 // with different card data
131 alert(`Declined: ${response.responseData.resultText}`);
132 payComponent.payabliExec("reinit");
133 break;
134 default:
135 // Other response text. These are normally errors with Payabli internal validations
136 // before processor engagement
137 // We recommend reinitializing the component.
138 // If the problem persists, contact Payabli to help debug
139 alert(`Error: ${response.responseText}`);
140 payComponent.payabliExec("reinit");
141 break;
142 }
143 },
144 functionCallBackError: function(errors) {
145 console.log("Payment error:", errors);
146 alert("Payment processing error occurred");
147 payComponent.payabliExec("reinit");
148 },
149 functionCallBackReady: function(data) {
150 const btn = document.getElementById("submit-btn");
151 if (data[1] === true) {
152 btn.classList.remove("hidden");
153 } else {
154 btn.classList.add("hidden");
155 }
156 }
157 };
158
159 const achConfig = {
160 type: "methodEmbedded",
161 rootContainer: "pay-component-1",
162 token: "your-public-api-token",
163 entryPoint: "your-entry-point",
164 defaultOpen: "ach",
165 temporaryToken: false,
166 ach: {
167 enabled: true,
168 checking: true,
169 savings: true,
170 inputs: {
171 achAccountHolderName: {
172 label: "ACCOUNT HOLDER NAME",
173 placeholder: "Account Holder Name",
174 floating: false,
175 size: 6,
176 row: 0,
177 order: 0
178 },
179 achRouting: {
180 label: "ROUTING NUMBER",
181 placeholder: "123456789",
182 floating: false,
183 size: 6,
184 row: 1,
185 order: 0
186 },
187 achAccount: {
188 label: "ACCOUNT NUMBER",
189 placeholder: "Account Number",
190 floating: false,
191 size: 6,
192 row: 1,
193 order: 1
194 },
195 achAccountType: {
196 label: "ACCOUNT TYPE",
197 floating: false,
198 size: 6,
199 row: 0,
200 order: 1
201 }
202 }
203 },
204 functionCallBackSuccess: function (response) {
205 // This callback covers both 2XX and 4XX responses
206 console.log(response);
207 switch (response.responseText) {
208 case "Success":
209 // Tokenization was successful
210 alert(`Success: ${response.responseData.resultText}`);
211 break;
212 case "Declined":
213 // Tokenization failed due to processor decline or validation errors
214 // Recommend reinitialization of the component so that the user can try again
215 // with different card data
216 alert(`Declined: ${response.responseData.resultText}`);
217 payComponent.payabliExec("reinit");
218 break;
219 default:
220 // Other response text. These are normally errors with Payabli internal validations
221 // before processor engagement
222 // We recommend reinitializing the component.
223 // If the problem persists, contact Payabli to help debug
224 alert(`Error: ${response.responseText}`);
225 payComponent.payabliExec("reinit");
226 break;
227 }
228 },
229 functionCallBackError: function(errors) {
230 console.log("Payment error:", errors);
231 alert("Payment processing error occurred");
232 payComponent.payabliExec("reinit");
233 },
234 functionCallBackReady: function(data) {
235 const btn = document.getElementById("submit-btn");
236 if (data[1] === true) {
237 btn.classList.remove("hidden");
238 } else {
239 btn.classList.add("hidden");
240 }
241 }
242 };
243
244 // Tab switching
245 document.querySelectorAll('.tab').forEach(tab => {
246 tab.addEventListener('click', function() {
247 const method = this.dataset.method;
248
249 // Update active tab
250 document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
251 this.classList.add('active');
252
253 // Create new component with appropriate config
254 if (method === 'card') {
255 payComponent = new PayabliComponent(cardConfig);
256 } else {
257 payComponent = new PayabliComponent(achConfig);
258 }
259 });
260 });
261 </script>
262</body>
263</html>

/// Initialize and Execute Payment

Use the payabliExec method to perform payment processing logic. The final step creates a working payment form that can process real transactions or save payment methods securely.

-284
1<!DOCTYPE html>
2<html>
3<head>
4 <meta charset="UTF-8">
5 <title>Payabli Integration</title>
6 <style>
7 .tabs {
8 display: flex;
9 border-bottom: 1px solid #e5e5e5;
10 margin-bottom: 20px;
11 }
12
13 .tab {
14 flex: 1;
15 padding: 16px 24px;
16 text-align: center;
17 cursor: pointer;
18 background: white;
19 border: none;
20 border-bottom: 2px solid transparent;
21 transition: all 0.2s ease;
22 }
23
24 .tab:hover {
25 color: #333;
26 background: #f8f9fa;
27 }
28
29 .tab.active {
30 color: #007bff;
31 border-bottom-color: #007bff;
32 }
33
34 .hidden {
35 display: none;
36 }
37
38 #submit-btn {
39 background: #4f46e5;
40 color: white;
41 padding: 12px 24px;
42 border: none;
43 border-radius: 6px;
44 cursor: pointer;
45 margin-top: 16px;
46 }
47
48 #submit-btn:disabled {
49 background: #9ca3af;
50 cursor: not-allowed;
51 }
52 </style>
53</head>
54<body>
55 <h1>Payment Form</h1>
56 <p>Enter your payment information below:</p>
57 <div class="payment-container">
58 <div class="tabs">
59 <button class="tab active" data-method="card">Payment Card</button>
60 <button class="tab" data-method="ach">Bank Debit</button>
61 </div>
62 <div class="form-content">
63 <div id="pay-component-1"></div>
64 <button id="submit-btn" class="hidden">Process Payment</button>
65 </div>
66 </div>
67
68 <script src="https://embedded-component-sandbox.payabli.com/component.js" data-test></script>
69 <script>
70 let payComponent;
71
72 const cardConfig = {
73 type: "methodEmbedded",
74 rootContainer: "pay-component-1",
75 token: "your-public-api-token",
76 entryPoint: "your-entry-point",
77 defaultOpen: "card",
78 temporaryToken: false,
79 card: {
80 enabled: true,
81 amex: true,
82 discover: true,
83 visa: true,
84 mastercard: true,
85 jcb: true,
86 diners: true,
87 inputs: {
88 cardHolderName: {
89 label: "NAME ON CARD",
90 size: 12,
91 row: 0,
92 order: 0
93 },
94 cardNumber: {
95 label: "CARD NUMBER",
96 size: 6,
97 row: 1,
98 order: 0
99 },
100 cardExpirationDate: {
101 label: "EXPIRATION",
102 size: 6,
103 row: 1,
104 order: 1
105 },
106 cardCvv: {
107 label: "CVV",
108 size: 6,
109 row: 2,
110 order: 0
111 },
112 cardZipcode: {
113 label: "ZIP CODE",
114 size: 6,
115 row: 2,
116 order: 1
117 }
118 }
119 },
120 functionCallBackSuccess: function (response) {
121 // This callback covers both 2XX and 4XX responses
122 console.log(response);
123 switch (response.responseText) {
124 case "Success":
125 // Tokenization was successful
126 alert(`Success: ${response.responseData.resultText}`);
127 break;
128 case "Declined":
129 // Tokenization failed due to processor decline or validation errors
130 // Recommend reinitialization of the component so that the user can try again
131 // with different card data
132 alert(`Declined: ${response.responseData.resultText}`);
133 payComponent.payabliExec("reinit");
134 break;
135 default:
136 // Other response text. These are normally errors with Payabli internal validations
137 // before processor engagement
138 // We recommend reinitializing the component.
139 // If the problem persists, contact Payabli to help debug
140 alert(`Error: ${response.responseText}`);
141 payComponent.payabliExec("reinit");
142 break;
143 }
144 },
145 functionCallBackError: function(errors) {
146 console.log("Payment error:", errors);
147 alert("Payment processing error occurred");
148 payComponent.payabliExec("reinit");
149 },
150 functionCallBackReady: function(data) {
151 const btn = document.getElementById("submit-btn");
152 if (data[1] === true) {
153 btn.classList.remove("hidden");
154 } else {
155 btn.classList.add("hidden");
156 }
157 }
158 };
159
160 const achConfig = {
161 type: "methodEmbedded",
162 rootContainer: "pay-component-1",
163 token: "your-public-api-token",
164 entryPoint: "your-entry-point",
165 defaultOpen: "ach",
166 temporaryToken: false,
167 ach: {
168 enabled: true,
169 checking: true,
170 savings: true,
171 inputs: {
172 achAccountHolderName: {
173 label: "ACCOUNT HOLDER NAME",
174 placeholder: "Account Holder Name",
175 floating: false,
176 size: 6,
177 row: 0,
178 order: 0
179 },
180 achRouting: {
181 label: "ROUTING NUMBER",
182 placeholder: "123456789",
183 floating: false,
184 size: 6,
185 row: 1,
186 order: 0
187 },
188 achAccount: {
189 label: "ACCOUNT NUMBER",
190 placeholder: "Account Number",
191 floating: false,
192 size: 6,
193 row: 1,
194 order: 1
195 },
196 achAccountType: {
197 label: "ACCOUNT TYPE",
198 floating: false,
199 size: 6,
200 row: 0,
201 order: 1
202 }
203 }
204 },
205 functionCallBackSuccess: function (response) {
206 // This callback covers both 2XX and 4XX responses
207 console.log(response);
208 switch (response.responseText) {
209 case "Success":
210 // Tokenization was successful
211 alert(`Success: ${response.responseData.resultText}`);
212 break;
213 case "Declined":
214 // Tokenization failed due to processor decline or validation errors
215 // Recommend reinitialization of the component so that the user can try again
216 // with different card data
217 alert(`Declined: ${response.responseData.resultText}`);
218 payComponent.payabliExec("reinit");
219 break;
220 default:
221 // Other response text. These are normally errors with Payabli internal validations
222 // before processor engagement
223 // We recommend reinitializing the component.
224 // If the problem persists, contact Payabli to help debug
225 alert(`Error: ${response.responseText}`);
226 payComponent.payabliExec("reinit");
227 break;
228 }
229 },
230 functionCallBackError: function(errors) {
231 console.log("Payment error:", errors);
232 alert("Payment processing error occurred");
233 payComponent.payabliExec("reinit");
234 },
235 functionCallBackReady: function(data) {
236 const btn = document.getElementById("submit-btn");
237 if (data[1] === true) {
238 btn.classList.remove("hidden");
239 } else {
240 btn.classList.add("hidden");
241 }
242 }
243 };
244
245 // Tab switching
246 document.querySelectorAll('.tab').forEach(tab => {
247 tab.addEventListener('click', function() {
248 const method = this.dataset.method;
249
250 // Update active tab
251 document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
252 this.classList.add('active');
253
254 // Create new component with appropriate config
255 if (method === 'card') {
256 payComponent = new PayabliComponent(cardConfig);
257 } else {
258 payComponent = new PayabliComponent(achConfig);
259 }
260 });
261 });
262
263 // Initialize the Payabli component
264 payComponent = new PayabliComponent(cardConfig);
265
266 // Handle payment execution
267 document.getElementById("submit-btn").addEventListener("click", function() {
268 payComponent.payabliExec('pay', {
269 paymentDetails: {
270 totalAmount: 100.00,
271 serviceFee: 0,
272 categories: [{
273 label: "payment",
274 amount: 100.00,
275 qty: 1
276 }]
277 },
278 customerData: {
279 firstName: "John",
280 lastName: "Doe",
281 billingEmail: "john.doe@example.com"
282 }
283 });
284 });
285 </script>
286</body>
287</html>

Configuration reference

These are the configuration parameters available for the EmbeddedMethod component. If you need to pass more than data than what’s supported, consider using the temporary token flow. See Temporary Token Flow for more information.

type
stringRequired

This value determines the type of embedded component to render.
Accepted values are: methodEmbedded, methodLightbox, vterminal, or expressCheckout.
For the EmbeddedMethod UI, this value is methodEmbedded. See the Embedded Components Overview for more information on other component types.

rootContainer
stringRequired

Container ID used for the component.

defaultOpen
string

Sets the default payment method that’s shown. Accepted values are: card or ach.

hideComponent
booleanDefaults to false

When true the component is hidden when it’s instanced.

token
stringRequired

API token for authentication. This should be a public API token, as described here.

forceCustomerCreation
booleanDefaults to true

When true, the component uses the customerData object to create a new customer record. When temporaryToken is true and forceCustomerCreation is false, the component doesn’t create a new customer record. See Temporary Token Flow for more information.

customCssUrl
string

Complete URL of a custom CSS stylesheet to use with the component.

clearFormAfterSubmit
booleanDefaults to true

When true, the entered values on the form are cleared when submitted.

temporaryToken
booleanDefaults to true

When true, the token created for the payment is temporary. Set this parameter to false to create a storedMethodId and save the payment profile.

showPopoverError
booleanDefaults to true

When false, the validation error appears below the field instead of above it in a popover.

entryPoint
string

When the API token belongs to an organization, the entrypoint name identifies the target paypoint (merchant).

card
objectRequired

cardService object used to configure accepted card types.

enabled
boolean

Enable/disable card option.

amex
boolean

Enable/disable acceptance of American Express cards.

discover
boolean

Enable/disable acceptance of Discover cards.

visa
boolean

Enable/disable acceptance of Visa cards.

mastercard
boolean

Enable/disable acceptance of MasterCard cards.

diners
boolean

Enable/disable acceptance of Diner’s Club cards.

jcb
boolean

Enable/disable acceptance of JCB cards.

inputs
object

Card input fields descriptors. This object applies only to the EmbeddedMethod UI component.

cardHolderName
object

Optional, but strongly recommended. Descriptor object for input field.

cardNumber
objectRequired

Descriptor object for input field.

cardExpirationDate
objectRequired

Descriptor object for input field.

cardCvv
objectRequired

Descriptor object for input field.

cardZipcode
object

Optional, but strongly recommended. Descriptor object for input field.

ach
objectRequired

achService object used to configure accepted ACH types.

enabled
boolean

Enable/disable ACH option.

checking
boolean

Enable/disable acceptance of Checking account.

savings
boolean

Enable/disable acceptance of Savings account.

achValidation
booleanDefaults to false

When set to true, the embedded component will validate ACH account and routing numbers in real time. This is an add-on feature. Contact the Payabli team for more information.

inputs
object

ACH input field descriptors. This only applies to the EmbeddedMethod UI component.

achAccountHolderName
objectRequired

Required. Descriptor object for input field.

achAccountType
objectRequired

Required. Descriptor object for input field.

achRouting
objectRequired

Required. Descriptor object for input field. Use the confirm input descriptor to add matching validation to this field. See Style Individual Fields for more.

achAccount
objectRequired

Required. Descriptor object for input field. Use the confirm input descriptor to add matching validation to this field. See Style Individual Fields for more.

paymentMethod
objectRequired

paymentMethod object with data related to the payment method. Required when saving a payment method or executing a payment. Can be passed to the component via payabliExec method.

customerData
objectRequired

Customer Object with data related to customer. Can be passed to the component as a parameter with the payabliExec method. Required when saving a payment method. Which fields are required depends on whether the paypoint has custom identifiers. If you aren’t using custom identifiers, then you must include at least one of these values: firstname and lastname, email, or customerId.

paymentDetails
objectRequired

paymentDetails object with data related to the payment. Required to save a payment method. Can be passed to the component via payabliExec method.

fallbackAuth
boolean | nullDefaults to false

When true, if tokenization fails, Payabli will attempt an authorization transaction to request a permanent token for the card. If the authorization is successful, the card will be tokenized and the authorization will be voided automatically.

fallbackAuthAmount
number | nullDefaults to 1.00

The amount for the fallbackAuth transaction. Defaults to one dollar.

functionCallBackSuccess
function

The callback function called when the component executes successfully.

functionCallBackError
function

The callback function called when the component receives an error. See functionCallBackError response in the next section for a complete reference.

functionCallBackReady
function

The callback function called when the component’s status changes. Used to poll the form’s completeness before showing the submit button.

Response

The embedded component returns a response object to the callback functions defined in the configuration. The response object contains the result of the transaction (success, declined, or error) and details about the transaction.

Response examples

Click the tab to see an example response returned by the embedded component for each result.

1{
2 responseText: "Success",
3 responseData: {
4 authCode: "123456",
5 referenceId: "40-692c62895d1541d28c0bf77b275a26e4",
6 resultCode: 1,
7 resultText: "Approved",
8 avsResponseText: "",
9 cvvResponseText: "",
10 customerId: 706,
11 methodReferenceId: null
12 }
13}

Response reference

The response object passed to a callback function has the following structure:

responseText
string

“Success” or “Declined”

responseData
object

Container for response details.

responseData.AuthCode
string

Authorization code for payments. This field has a value of null for saved payment methods.

responseData.ReferenceId
string

Identifier for the transaction (for payments) or the stored payment method (for save payment method).

responseData.ResultCode
integer

Result of operation. 1 is success, 2 is declined, and 3 is error.

responseData.ResultText
string

Message related the result. If the operation was successful, it returns “Added”/“Approved”. If there was an error, it returns error details.

responseData.AvsResponseText
string

Result of address validation for card transactions. This field is an empty string when processing ACH transactions. This field doesn’t exist when saving payment methods.

responseData.CvvResponseText
string

Result of CVV validation for card transactions. This field is an empty string when processing ACH transactions. This field doesn’t exist when saving payment methods.

responseData.CustomerId
integer

ID for the customer owner of payment or saved payment method.

responseData.methodReferenceId
string

Identifier for stored payment method for saved payment methods. This field has a value of null for payment transactions. The methodReferenceId is used as the storedMethodId in other operations. See Handling responses and errors for more.

functionCallBackError response

The functionCallBackError function is called when the component can’t validate the payment information before submitting it to Payabli’s API. The response object passed to functionCallBackError contains an array with codes, keys, and descriptions of failed validations. You can check the values in the array to offer your customized error message.

CodeKeyDescription
802paymentMethodsCardNumberErrorError in Card number field
803paymentMethodsCardExpirationDateErrorError in Card Expiration field
804paymentMethodsCardCvvErrorError in CardCVV field
805paymentMethodsCardZipcodeErrorError in Card Zip code field
901paymentMethodsAchAccountHolderNameErrorError in ACH Holder field
902paymentMethodsAchAccountTypeErrorError in ACH Account type field
903paymentMethodsAchRoutingErrorError in ACH Routing field
904paymentMethodsAchAccountErrorError in ACH Account number field

Usage Flows

These flowcharts illustrate the path to making a payment or storing a payment method using an embedded component.

Make a payment

To make a payment with an embedded component, your component configuration should contain payabliExec(pay, parameters). In the parameters argument, include customerData and paymentDetails objects. When the payment is executed, the request returns response data.

This flowchart explains the basic steps for the task. Hover over a step for more information.

Run payabliExec(pay, parameters) The action is set to pay here. Send the paymentDetail and customerData object in parameters.

Payment executed The transaction is executed and includes the data sent as parameters

Response

Save a payment method

To save a payment method with an embedded component, your component configuration should contain payabliExec(method, parameters). In the parameters argument, include customerData and paymentDetails objects. When the payment method is saved, the request returns response data.

This flowchart explains the basic steps for the task. Hover over a step for more information.

Run payabliExec(method, parameters) The action is set to method here. Send the paymentDetail and customerData object in parameters.

Payment method saved The payment method is saved and includes the data sent as parameters

Response

Save a payment method and make a payment

You can save a payment method and make a payment with the EmbeddedMethod UI component by writing a callback function to execute the payment after successfully saving the payment method.

To save a payment method and then execute a transaction with the saved payment method, your component configuration should contain payabliExec(method, parameters). In the parameters argument, include the customerData and paymentDetails objects. When the payment method is saved, use a callback function to execute the transaction.

Remember to never make payment transactions via client-side API requests. Your callback function should make the payment transaction using a server-side function.

This flowchart explains the basic steps for the task. Hover over a step for more information.

Run payabliExec(method, parameters) Here, the action is set to method. Send the paymentDetail and customerData object in parameters.

Payment method saved The payment method is saved and includes the data sent as parameters. An ID for the payment method is returned, which is then used to make transactions.

Callback function Use a callback function to send a transaction that uses the new payment method.

Response