@bloque/payments-core 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/dist/checkout.d.ts +54 -0
- package/dist/index.cjs +164 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.js +141 -0
- package/dist/types.d.ts +93 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# @bloque/payments-core
|
|
2
|
+
|
|
3
|
+
Core JavaScript library for integrating Bloque hosted checkout into any web application.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm install @bloque/payments-core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
import { createCheckout } from '@bloque/payments-core';
|
|
15
|
+
|
|
16
|
+
// First, create a payment intent using @bloque/payments on your backend
|
|
17
|
+
// Then use the checkout_id to mount the checkout
|
|
18
|
+
const checkout = createCheckout({
|
|
19
|
+
checkoutId: 'checkout_123abc',
|
|
20
|
+
container: '#checkout-container',
|
|
21
|
+
onSuccess: (data) => {
|
|
22
|
+
console.log('Payment successful!', data);
|
|
23
|
+
},
|
|
24
|
+
onError: (error) => {
|
|
25
|
+
console.error('Payment failed:', error);
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Later, cleanup
|
|
30
|
+
checkout.destroy();
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Documentation
|
|
34
|
+
|
|
35
|
+
For complete documentation, examples, and API reference, visit:
|
|
36
|
+
|
|
37
|
+
**[https://docs.bloque.app/pay](https://docs.bloque.app/pay)**
|
|
38
|
+
|
|
39
|
+
## License
|
|
40
|
+
|
|
41
|
+
[MIT](../../LICENSE)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { BloqueCheckoutOptions, BloqueInitOptions } from './types';
|
|
2
|
+
export declare class BloqueCheckout {
|
|
3
|
+
private static globalConfig;
|
|
4
|
+
private iframe;
|
|
5
|
+
private options;
|
|
6
|
+
private messageListener;
|
|
7
|
+
private isReady;
|
|
8
|
+
/**
|
|
9
|
+
* Initialize global configuration for all BloqueCheckout instances
|
|
10
|
+
* This allows you to set publicApiKey and mode once instead of passing them to every checkout
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* BloqueCheckout.init({
|
|
15
|
+
* publicApiKey: 'pk_test_...',
|
|
16
|
+
* mode: 'sandbox'
|
|
17
|
+
* });
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
static init(config: BloqueInitOptions): void;
|
|
21
|
+
static getGlobalConfig(): BloqueInitOptions | null;
|
|
22
|
+
constructor(options: BloqueCheckoutOptions);
|
|
23
|
+
createIframe(): HTMLIFrameElement;
|
|
24
|
+
mount(container: HTMLElement | string): void;
|
|
25
|
+
private setupMessageListener;
|
|
26
|
+
private handleCheckoutReady;
|
|
27
|
+
private handlePaymentResult;
|
|
28
|
+
private handlePaymentError;
|
|
29
|
+
isCheckoutReady(): boolean;
|
|
30
|
+
getIframe(): HTMLIFrameElement | null;
|
|
31
|
+
updateOptions(options: Partial<BloqueCheckoutOptions>): void;
|
|
32
|
+
destroy(): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Initialize global configuration for all BloqueCheckout instances
|
|
36
|
+
* This is a convenience wrapper around BloqueCheckout.init()
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { init } from '@bloque/payments-core';
|
|
41
|
+
*
|
|
42
|
+
* init({
|
|
43
|
+
* publicApiKey: 'pk_test_...',
|
|
44
|
+
* mode: 'sandbox'
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function init(config: BloqueInitOptions): void;
|
|
49
|
+
/**
|
|
50
|
+
* Helper function to create and mount a checkout in one step
|
|
51
|
+
*/
|
|
52
|
+
export declare function createCheckout(options: BloqueCheckoutOptions & {
|
|
53
|
+
container: HTMLElement | string;
|
|
54
|
+
}): BloqueCheckout;
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
3
14
|
(()=>{
|
|
4
15
|
__webpack_require__.r = (exports1)=>{
|
|
5
16
|
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
@@ -12,7 +23,159 @@ var __webpack_require__ = {};
|
|
|
12
23
|
})();
|
|
13
24
|
var __webpack_exports__ = {};
|
|
14
25
|
__webpack_require__.r(__webpack_exports__);
|
|
15
|
-
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
BloqueCheckout: ()=>BloqueCheckout,
|
|
28
|
+
createCheckout: ()=>createCheckout,
|
|
29
|
+
init: ()=>init
|
|
30
|
+
});
|
|
31
|
+
const DEFAULT_CHECKOUT_URL = 'http://payments.bloque.app/checkout';
|
|
32
|
+
class BloqueCheckout {
|
|
33
|
+
static globalConfig = null;
|
|
34
|
+
iframe = null;
|
|
35
|
+
options;
|
|
36
|
+
messageListener = null;
|
|
37
|
+
isReady = false;
|
|
38
|
+
static init(config) {
|
|
39
|
+
BloqueCheckout.globalConfig = config;
|
|
40
|
+
}
|
|
41
|
+
static getGlobalConfig() {
|
|
42
|
+
return BloqueCheckout.globalConfig;
|
|
43
|
+
}
|
|
44
|
+
constructor(options){
|
|
45
|
+
if (!options.checkoutId) throw new Error('[BloqueCheckout] checkoutId is required');
|
|
46
|
+
const publicApiKey = options.publicApiKey || BloqueCheckout.globalConfig?.publicApiKey;
|
|
47
|
+
const mode = options.mode || BloqueCheckout.globalConfig?.mode || 'production';
|
|
48
|
+
const checkoutUrl = options.checkoutUrl || BloqueCheckout.globalConfig?.checkoutUrl || DEFAULT_CHECKOUT_URL;
|
|
49
|
+
if (!publicApiKey) throw new Error('[BloqueCheckout] publicApiKey is required. Either pass it as an option or call BloqueCheckout.init() first.');
|
|
50
|
+
this.options = {
|
|
51
|
+
checkoutId: options.checkoutId,
|
|
52
|
+
publicApiKey,
|
|
53
|
+
mode,
|
|
54
|
+
checkoutUrl,
|
|
55
|
+
appearance: options.appearance,
|
|
56
|
+
onReady: options.onReady,
|
|
57
|
+
onSuccess: options.onSuccess,
|
|
58
|
+
onError: options.onError,
|
|
59
|
+
onPending: options.onPending,
|
|
60
|
+
iframeStyles: options.iframeStyles
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
createIframe() {
|
|
64
|
+
if (this.iframe) return this.iframe;
|
|
65
|
+
this.iframe = document.createElement('iframe');
|
|
66
|
+
let iframeUrl = this.options.checkoutUrl;
|
|
67
|
+
if (this.options.appearance) {
|
|
68
|
+
const params = new URLSearchParams();
|
|
69
|
+
if (this.options.appearance.primaryColor) params.set('primaryColor', this.options.appearance.primaryColor);
|
|
70
|
+
if (this.options.appearance.borderRadius) params.set('borderRadius', this.options.appearance.borderRadius);
|
|
71
|
+
if (this.options.appearance.fontFamily) params.set('fontFamily', this.options.appearance.fontFamily);
|
|
72
|
+
const queryString = params.toString();
|
|
73
|
+
if (queryString) iframeUrl = `${iframeUrl}?${queryString}`;
|
|
74
|
+
}
|
|
75
|
+
this.iframe.src = iframeUrl;
|
|
76
|
+
this.iframe.setAttribute('frameborder', '0');
|
|
77
|
+
this.iframe.setAttribute('allowtransparency', 'true');
|
|
78
|
+
this.iframe.setAttribute('allow', 'payment');
|
|
79
|
+
const defaultStyles = {
|
|
80
|
+
width: '100%',
|
|
81
|
+
height: '600px',
|
|
82
|
+
border: 'none',
|
|
83
|
+
borderRadius: '8px'
|
|
84
|
+
};
|
|
85
|
+
const styles = {
|
|
86
|
+
...defaultStyles,
|
|
87
|
+
...this.options.iframeStyles
|
|
88
|
+
};
|
|
89
|
+
for (const [key, value] of Object.entries(styles))if (null != value) this.iframe.style[key] = value;
|
|
90
|
+
this.setupMessageListener();
|
|
91
|
+
return this.iframe;
|
|
92
|
+
}
|
|
93
|
+
mount(container) {
|
|
94
|
+
const containerElement = 'string' == typeof container ? document.getElementById(container) || document.querySelector(container) : container;
|
|
95
|
+
if (!containerElement) throw new Error('Container element not found');
|
|
96
|
+
const iframe = this.createIframe();
|
|
97
|
+
containerElement.appendChild(iframe);
|
|
98
|
+
}
|
|
99
|
+
setupMessageListener() {
|
|
100
|
+
this.messageListener = (event)=>{
|
|
101
|
+
const { type, data, error } = event.data || {};
|
|
102
|
+
switch(type){
|
|
103
|
+
case 'checkout-ready':
|
|
104
|
+
this.handleCheckoutReady();
|
|
105
|
+
break;
|
|
106
|
+
case 'payment-result':
|
|
107
|
+
if (data) this.handlePaymentResult(data);
|
|
108
|
+
break;
|
|
109
|
+
case 'payment-error':
|
|
110
|
+
if (error) this.handlePaymentError(error);
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
window.addEventListener('message', this.messageListener);
|
|
117
|
+
}
|
|
118
|
+
handleCheckoutReady() {
|
|
119
|
+
this.isReady = true;
|
|
120
|
+
if (this.iframe?.contentWindow) this.iframe.contentWindow.postMessage({
|
|
121
|
+
type: 'checkout-init',
|
|
122
|
+
checkoutId: this.options.checkoutId,
|
|
123
|
+
publicApiKey: this.options.publicApiKey,
|
|
124
|
+
mode: this.options.mode
|
|
125
|
+
}, '*');
|
|
126
|
+
this.options.onReady?.();
|
|
127
|
+
}
|
|
128
|
+
handlePaymentResult(data) {
|
|
129
|
+
if ('approved' === data.status) this.options.onSuccess?.(data);
|
|
130
|
+
else if ('pending' === data.status) this.options.onPending?.(data);
|
|
131
|
+
else if ('rejected' === data.status) this.options.onError?.(data.message || 'Payment was rejected');
|
|
132
|
+
}
|
|
133
|
+
handlePaymentError(error) {
|
|
134
|
+
this.options.onError?.(error);
|
|
135
|
+
}
|
|
136
|
+
isCheckoutReady() {
|
|
137
|
+
return this.isReady;
|
|
138
|
+
}
|
|
139
|
+
getIframe() {
|
|
140
|
+
return this.iframe;
|
|
141
|
+
}
|
|
142
|
+
updateOptions(options) {
|
|
143
|
+
this.options = {
|
|
144
|
+
...this.options,
|
|
145
|
+
...options,
|
|
146
|
+
checkoutUrl: options.checkoutUrl || this.options.checkoutUrl,
|
|
147
|
+
mode: options.mode || this.options.mode
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
destroy() {
|
|
151
|
+
if (this.iframe) {
|
|
152
|
+
this.iframe.remove();
|
|
153
|
+
this.iframe = null;
|
|
154
|
+
}
|
|
155
|
+
if (this.messageListener) {
|
|
156
|
+
window.removeEventListener('message', this.messageListener);
|
|
157
|
+
this.messageListener = null;
|
|
158
|
+
}
|
|
159
|
+
this.isReady = false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function init(config) {
|
|
163
|
+
BloqueCheckout.init(config);
|
|
164
|
+
}
|
|
165
|
+
function createCheckout(options) {
|
|
166
|
+
const { container, ...checkoutOptions } = options;
|
|
167
|
+
const checkout = new BloqueCheckout(checkoutOptions);
|
|
168
|
+
checkout.mount(container);
|
|
169
|
+
return checkout;
|
|
170
|
+
}
|
|
171
|
+
exports.BloqueCheckout = __webpack_exports__.BloqueCheckout;
|
|
172
|
+
exports.createCheckout = __webpack_exports__.createCheckout;
|
|
173
|
+
exports.init = __webpack_exports__.init;
|
|
174
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
175
|
+
"BloqueCheckout",
|
|
176
|
+
"createCheckout",
|
|
177
|
+
"init"
|
|
178
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
16
179
|
Object.defineProperty(exports, '__esModule', {
|
|
17
180
|
value: true
|
|
18
181
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
export type {
|
|
3
|
-
export type { CreatePaymentParams, PaymentMethodType, PaymentResponse, } from './types/payment';
|
|
4
|
-
export type { PaymentSubmitPayload } from './types/payment-submit';
|
|
5
|
-
export type { PSEPaymentFormData } from './types/pse-payment';
|
|
1
|
+
export { BloqueCheckout, createCheckout, init } from './checkout';
|
|
2
|
+
export type { AppearanceConfig, BloqueCheckoutOptions, BloqueInitOptions, CheckoutMessage, CheckoutMessageType, PaymentResult, } from './types';
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
const DEFAULT_CHECKOUT_URL = 'http://payments.bloque.app/checkout';
|
|
2
|
+
class BloqueCheckout {
|
|
3
|
+
static globalConfig = null;
|
|
4
|
+
iframe = null;
|
|
5
|
+
options;
|
|
6
|
+
messageListener = null;
|
|
7
|
+
isReady = false;
|
|
8
|
+
static init(config) {
|
|
9
|
+
BloqueCheckout.globalConfig = config;
|
|
10
|
+
}
|
|
11
|
+
static getGlobalConfig() {
|
|
12
|
+
return BloqueCheckout.globalConfig;
|
|
13
|
+
}
|
|
14
|
+
constructor(options){
|
|
15
|
+
if (!options.checkoutId) throw new Error('[BloqueCheckout] checkoutId is required');
|
|
16
|
+
const publicApiKey = options.publicApiKey || BloqueCheckout.globalConfig?.publicApiKey;
|
|
17
|
+
const mode = options.mode || BloqueCheckout.globalConfig?.mode || 'production';
|
|
18
|
+
const checkoutUrl = options.checkoutUrl || BloqueCheckout.globalConfig?.checkoutUrl || DEFAULT_CHECKOUT_URL;
|
|
19
|
+
if (!publicApiKey) throw new Error('[BloqueCheckout] publicApiKey is required. Either pass it as an option or call BloqueCheckout.init() first.');
|
|
20
|
+
this.options = {
|
|
21
|
+
checkoutId: options.checkoutId,
|
|
22
|
+
publicApiKey,
|
|
23
|
+
mode,
|
|
24
|
+
checkoutUrl,
|
|
25
|
+
appearance: options.appearance,
|
|
26
|
+
onReady: options.onReady,
|
|
27
|
+
onSuccess: options.onSuccess,
|
|
28
|
+
onError: options.onError,
|
|
29
|
+
onPending: options.onPending,
|
|
30
|
+
iframeStyles: options.iframeStyles
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
createIframe() {
|
|
34
|
+
if (this.iframe) return this.iframe;
|
|
35
|
+
this.iframe = document.createElement('iframe');
|
|
36
|
+
let iframeUrl = this.options.checkoutUrl;
|
|
37
|
+
if (this.options.appearance) {
|
|
38
|
+
const params = new URLSearchParams();
|
|
39
|
+
if (this.options.appearance.primaryColor) params.set('primaryColor', this.options.appearance.primaryColor);
|
|
40
|
+
if (this.options.appearance.borderRadius) params.set('borderRadius', this.options.appearance.borderRadius);
|
|
41
|
+
if (this.options.appearance.fontFamily) params.set('fontFamily', this.options.appearance.fontFamily);
|
|
42
|
+
const queryString = params.toString();
|
|
43
|
+
if (queryString) iframeUrl = `${iframeUrl}?${queryString}`;
|
|
44
|
+
}
|
|
45
|
+
this.iframe.src = iframeUrl;
|
|
46
|
+
this.iframe.setAttribute('frameborder', '0');
|
|
47
|
+
this.iframe.setAttribute('allowtransparency', 'true');
|
|
48
|
+
this.iframe.setAttribute('allow', 'payment');
|
|
49
|
+
const defaultStyles = {
|
|
50
|
+
width: '100%',
|
|
51
|
+
height: '600px',
|
|
52
|
+
border: 'none',
|
|
53
|
+
borderRadius: '8px'
|
|
54
|
+
};
|
|
55
|
+
const styles = {
|
|
56
|
+
...defaultStyles,
|
|
57
|
+
...this.options.iframeStyles
|
|
58
|
+
};
|
|
59
|
+
for (const [key, value] of Object.entries(styles))if (null != value) this.iframe.style[key] = value;
|
|
60
|
+
this.setupMessageListener();
|
|
61
|
+
return this.iframe;
|
|
62
|
+
}
|
|
63
|
+
mount(container) {
|
|
64
|
+
const containerElement = 'string' == typeof container ? document.getElementById(container) || document.querySelector(container) : container;
|
|
65
|
+
if (!containerElement) throw new Error('Container element not found');
|
|
66
|
+
const iframe = this.createIframe();
|
|
67
|
+
containerElement.appendChild(iframe);
|
|
68
|
+
}
|
|
69
|
+
setupMessageListener() {
|
|
70
|
+
this.messageListener = (event)=>{
|
|
71
|
+
const { type, data, error } = event.data || {};
|
|
72
|
+
switch(type){
|
|
73
|
+
case 'checkout-ready':
|
|
74
|
+
this.handleCheckoutReady();
|
|
75
|
+
break;
|
|
76
|
+
case 'payment-result':
|
|
77
|
+
if (data) this.handlePaymentResult(data);
|
|
78
|
+
break;
|
|
79
|
+
case 'payment-error':
|
|
80
|
+
if (error) this.handlePaymentError(error);
|
|
81
|
+
break;
|
|
82
|
+
default:
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
window.addEventListener('message', this.messageListener);
|
|
87
|
+
}
|
|
88
|
+
handleCheckoutReady() {
|
|
89
|
+
this.isReady = true;
|
|
90
|
+
if (this.iframe?.contentWindow) this.iframe.contentWindow.postMessage({
|
|
91
|
+
type: 'checkout-init',
|
|
92
|
+
checkoutId: this.options.checkoutId,
|
|
93
|
+
publicApiKey: this.options.publicApiKey,
|
|
94
|
+
mode: this.options.mode
|
|
95
|
+
}, '*');
|
|
96
|
+
this.options.onReady?.();
|
|
97
|
+
}
|
|
98
|
+
handlePaymentResult(data) {
|
|
99
|
+
if ('approved' === data.status) this.options.onSuccess?.(data);
|
|
100
|
+
else if ('pending' === data.status) this.options.onPending?.(data);
|
|
101
|
+
else if ('rejected' === data.status) this.options.onError?.(data.message || 'Payment was rejected');
|
|
102
|
+
}
|
|
103
|
+
handlePaymentError(error) {
|
|
104
|
+
this.options.onError?.(error);
|
|
105
|
+
}
|
|
106
|
+
isCheckoutReady() {
|
|
107
|
+
return this.isReady;
|
|
108
|
+
}
|
|
109
|
+
getIframe() {
|
|
110
|
+
return this.iframe;
|
|
111
|
+
}
|
|
112
|
+
updateOptions(options) {
|
|
113
|
+
this.options = {
|
|
114
|
+
...this.options,
|
|
115
|
+
...options,
|
|
116
|
+
checkoutUrl: options.checkoutUrl || this.options.checkoutUrl,
|
|
117
|
+
mode: options.mode || this.options.mode
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
destroy() {
|
|
121
|
+
if (this.iframe) {
|
|
122
|
+
this.iframe.remove();
|
|
123
|
+
this.iframe = null;
|
|
124
|
+
}
|
|
125
|
+
if (this.messageListener) {
|
|
126
|
+
window.removeEventListener('message', this.messageListener);
|
|
127
|
+
this.messageListener = null;
|
|
128
|
+
}
|
|
129
|
+
this.isReady = false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function init(config) {
|
|
133
|
+
BloqueCheckout.init(config);
|
|
134
|
+
}
|
|
135
|
+
function createCheckout(options) {
|
|
136
|
+
const { container, ...checkoutOptions } = options;
|
|
137
|
+
const checkout = new BloqueCheckout(checkoutOptions);
|
|
138
|
+
checkout.mount(container);
|
|
139
|
+
return checkout;
|
|
140
|
+
}
|
|
141
|
+
export { BloqueCheckout, createCheckout, init };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export interface AppearanceConfig {
|
|
2
|
+
/**
|
|
3
|
+
* Primary color for buttons and accents
|
|
4
|
+
* @example '#6366f1'
|
|
5
|
+
*/
|
|
6
|
+
primaryColor?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Border radius for form elements
|
|
9
|
+
* @example '12px'
|
|
10
|
+
*/
|
|
11
|
+
borderRadius?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Font family for text
|
|
14
|
+
* @example 'Inter, system-ui, sans-serif'
|
|
15
|
+
*/
|
|
16
|
+
fontFamily?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface BloqueInitOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Your Bloque public API key
|
|
21
|
+
*/
|
|
22
|
+
publicApiKey: string;
|
|
23
|
+
/**
|
|
24
|
+
* Operation mode
|
|
25
|
+
* @default 'production'
|
|
26
|
+
*/
|
|
27
|
+
mode?: 'production' | 'sandbox';
|
|
28
|
+
/**
|
|
29
|
+
* The URL of the hosted checkout page
|
|
30
|
+
* @default 'https://payments.bloque.app/checkout'
|
|
31
|
+
*/
|
|
32
|
+
checkoutUrl?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface BloqueCheckoutOptions {
|
|
35
|
+
/**
|
|
36
|
+
* The checkout ID returned from your backend after creating a checkout session
|
|
37
|
+
*/
|
|
38
|
+
checkoutId: string;
|
|
39
|
+
/**
|
|
40
|
+
* Your Bloque public API key (optional if you called BloqueCheckout.init())
|
|
41
|
+
*/
|
|
42
|
+
publicApiKey?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Operation mode (optional if you called BloqueCheckout.init())
|
|
45
|
+
* @default 'production'
|
|
46
|
+
*/
|
|
47
|
+
mode?: 'production' | 'sandbox';
|
|
48
|
+
/**
|
|
49
|
+
* The URL of the hosted checkout page
|
|
50
|
+
* @default 'https://payments.bloque.app/checkout'
|
|
51
|
+
*/
|
|
52
|
+
checkoutUrl?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Appearance configuration for the checkout
|
|
55
|
+
*/
|
|
56
|
+
appearance?: AppearanceConfig;
|
|
57
|
+
/**
|
|
58
|
+
* Callback fired when the checkout iframe is ready to receive the checkout ID
|
|
59
|
+
*/
|
|
60
|
+
onReady?: () => void;
|
|
61
|
+
/**
|
|
62
|
+
* Callback fired when a payment is successfully approved
|
|
63
|
+
*/
|
|
64
|
+
onSuccess?: (data: PaymentResult) => void;
|
|
65
|
+
/**
|
|
66
|
+
* Callback fired when a payment fails or an error occurs
|
|
67
|
+
*/
|
|
68
|
+
onError?: (error: string) => void;
|
|
69
|
+
/**
|
|
70
|
+
* Callback fired when a payment is pending (e.g., waiting for bank confirmation)
|
|
71
|
+
*/
|
|
72
|
+
onPending?: (data: PaymentResult) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Custom CSS styles to apply to the iframe
|
|
75
|
+
*/
|
|
76
|
+
iframeStyles?: Record<string, string>;
|
|
77
|
+
}
|
|
78
|
+
export interface PaymentResult {
|
|
79
|
+
payment_id: string;
|
|
80
|
+
status: 'approved' | 'pending' | 'rejected';
|
|
81
|
+
message: string;
|
|
82
|
+
amount: number;
|
|
83
|
+
currency: string;
|
|
84
|
+
reference: string;
|
|
85
|
+
created_at: string;
|
|
86
|
+
}
|
|
87
|
+
export type CheckoutMessageType = 'checkout-ready' | 'checkout-init' | 'payment-result' | 'payment-error';
|
|
88
|
+
export interface CheckoutMessage {
|
|
89
|
+
type: CheckoutMessageType;
|
|
90
|
+
checkoutId?: string;
|
|
91
|
+
data?: PaymentResult;
|
|
92
|
+
error?: string;
|
|
93
|
+
}
|