@fat-zebra/sdk 1.0.5 → 1.2.1
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/CHANGELOG.md +13 -0
- package/README.md +162 -0
- package/dist/applepay/applepay.d.ts +20 -0
- package/dist/applepay/applepay.js +93 -0
- package/dist/applepay/clients/apple-pay-client.d.ts +24 -0
- package/dist/applepay/clients/apple-pay-client.js +29 -0
- package/dist/applepay/clients/paynow-client.d.ts +17 -0
- package/dist/applepay/clients/paynow-client.js +55 -0
- package/dist/applepay/index.d.ts +1 -0
- package/dist/applepay/index.js +1 -0
- package/dist/env.d.ts +5 -0
- package/dist/env.development.d.ts +5 -0
- package/dist/env.development.js +5 -0
- package/dist/env.js +5 -0
- package/dist/hpp/hpp.d.ts +61 -0
- package/dist/hpp/hpp.js +186 -0
- package/dist/hpp/index.d.ts +2 -0
- package/dist/hpp/index.js +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +6 -2
- package/dist/local/fatzebra.js +17728 -0
- package/dist/local/fatzebra.js.map +1 -0
- package/dist/local/index.html +247 -0
- package/dist/main.d.ts +38 -0
- package/dist/main.js +148 -0
- package/dist/paypal/paypal-button.d.ts +31 -0
- package/dist/paypal/paypal-button.js +199 -0
- package/dist/paypal/paypal-checkout.d.ts +21 -0
- package/dist/paypal/paypal-checkout.js +100 -0
- package/dist/paypal/types.d.ts +188 -0
- package/dist/paypal/types.js +5 -0
- package/dist/paypal/validation.d.ts +4 -0
- package/dist/paypal/validation.js +65 -0
- package/dist/react/VerifyCard.d.ts +2 -4
- package/dist/react/VerifyCard.js +3 -3
- package/dist/react/url.d.ts +3 -18
- package/dist/react/url.js +3 -29
- package/dist/react/useFatZebra.d.ts +2 -3
- package/dist/react/useFatZebra.js +7 -7
- package/dist/sca/cardinal.d.ts +1 -1
- package/dist/sca/cardinal.js +1 -1
- package/dist/sca/index.d.ts +8 -5
- package/dist/sca/index.js +26 -85
- package/dist/sca/sca.d.ts +42 -0
- package/dist/sca/sca.js +273 -0
- package/dist/sca/scenarios/index.d.ts +3 -2
- package/dist/sca/types.d.ts +1 -1
- package/dist/sca/types.js +1 -1
- package/dist/shared/api-gateway-client.d.ts +7 -0
- package/dist/shared/api-gateway-client.js +35 -1
- package/dist/shared/env.d.ts +5 -0
- package/dist/shared/env.development.d.ts +5 -0
- package/dist/shared/env.development.js +5 -0
- package/dist/shared/env.js +5 -0
- package/dist/shared/event-manager.d.ts +1 -1
- package/dist/shared/event-manager.js +0 -1
- package/dist/shared/post-message-client.d.ts +1 -1
- package/dist/shared/post-message-client.js +1 -1
- package/dist/shared/types.d.ts +40 -33
- package/dist/shared/types.js +7 -1
- package/dist/src/applepay/applepay.js +198 -0
- package/dist/src/applepay/applepay.js.map +1 -0
- package/dist/src/applepay/clients/apple-pay-client.js +66 -0
- package/dist/src/applepay/clients/apple-pay-client.js.map +1 -0
- package/dist/src/applepay/clients/paynow-client.js +96 -0
- package/dist/src/applepay/clients/paynow-client.js.map +1 -0
- package/dist/src/applepay/index.js +6 -0
- package/dist/src/applepay/index.js.map +1 -0
- package/dist/src/hpp/hpp.js +230 -0
- package/dist/src/hpp/hpp.js.map +1 -0
- package/dist/src/hpp/hpp.test.js +135 -0
- package/dist/src/hpp/hpp.test.js.map +1 -0
- package/dist/src/hpp/index.js +6 -0
- package/dist/src/hpp/index.js.map +1 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/main.js +225 -0
- package/dist/src/main.js.map +1 -0
- package/dist/src/main.test.js +236 -0
- package/dist/src/main.test.js.map +1 -0
- package/dist/src/paypal/paypal-button.js +311 -0
- package/dist/src/paypal/paypal-button.js.map +1 -0
- package/dist/src/paypal/paypal-button.test.js +41 -0
- package/dist/src/paypal/paypal-button.test.js.map +1 -0
- package/dist/src/paypal/paypal-checkout.js +111 -0
- package/dist/src/paypal/paypal-checkout.js.map +1 -0
- package/dist/src/paypal/paypal-checkout.test.js +167 -0
- package/dist/src/paypal/paypal-checkout.test.js.map +1 -0
- package/dist/src/paypal/types.js +9 -0
- package/dist/src/paypal/types.js.map +1 -0
- package/dist/src/paypal/validation.js +73 -0
- package/dist/src/paypal/validation.js.map +1 -0
- package/dist/src/sca/__tests__/eci-mappings.test.js +31 -0
- package/dist/src/sca/__tests__/eci-mappings.test.js.map +1 -0
- package/dist/src/sca/__tests__/index.test.js +558 -0
- package/dist/src/sca/__tests__/index.test.js.map +1 -0
- package/dist/src/sca/cardinal.js +110 -0
- package/dist/src/sca/cardinal.js.map +1 -0
- package/dist/src/sca/eci-mappings.js +63 -0
- package/dist/src/sca/eci-mappings.js.map +1 -0
- package/dist/src/sca/eci-mappings.test.js +31 -0
- package/dist/src/sca/eci-mappings.test.js.map +1 -0
- package/dist/src/sca/index.js +388 -0
- package/dist/src/sca/index.js.map +1 -0
- package/dist/src/sca/index.test.js +558 -0
- package/dist/src/sca/index.test.js.map +1 -0
- package/dist/src/sca/scenarios/enrollment.js +150 -0
- package/dist/src/sca/scenarios/enrollment.js.map +1 -0
- package/dist/src/sca/scenarios/index.js +8 -0
- package/dist/src/sca/scenarios/index.js.map +1 -0
- package/dist/src/sca/scenarios/validation.js +128 -0
- package/dist/src/sca/scenarios/validation.js.map +1 -0
- package/dist/src/sca/types.js +57 -0
- package/dist/src/sca/types.js.map +1 -0
- package/dist/src/shared/api-gateway-client.js +150 -0
- package/dist/src/shared/api-gateway-client.js.map +1 -0
- package/dist/src/shared/bridge-client.js +24 -0
- package/dist/src/shared/bridge-client.js.map +1 -0
- package/dist/src/shared/constants.js +19 -0
- package/dist/src/shared/constants.js.map +1 -0
- package/dist/src/shared/event-manager.js +15 -0
- package/dist/src/shared/event-manager.js.map +1 -0
- package/dist/src/shared/post-message-client.js +107 -0
- package/dist/src/shared/post-message-client.js.map +1 -0
- package/dist/src/shared/post-message-client.test.js +58 -0
- package/dist/src/shared/post-message-client.test.js.map +1 -0
- package/dist/src/shared/types.js +47 -0
- package/dist/src/shared/types.js.map +1 -0
- package/dist/src/shared/types.test.js +55 -0
- package/dist/src/shared/types.test.js.map +1 -0
- package/dist/src/shared/util.js +96 -0
- package/dist/src/shared/util.js.map +1 -0
- package/dist/src/shared/util.test.js +148 -0
- package/dist/src/shared/util.test.js.map +1 -0
- package/dist/src/validation/index.js +10 -0
- package/dist/src/validation/index.js.map +1 -0
- package/dist/src/validation/validation-helper.js +10 -0
- package/dist/src/validation/validation-helper.js.map +1 -0
- package/dist/src/validation/validation-helper.test.js +34 -0
- package/dist/src/validation/validation-helper.test.js.map +1 -0
- package/dist/src/validation/validators/hpp-load-params-validator.js +17 -0
- package/dist/src/validation/validators/hpp-load-params-validator.js.map +1 -0
- package/dist/src/validation/validators/hpp-load-params-validator.test.js +56 -0
- package/dist/src/validation/validators/hpp-load-params-validator.test.js.map +1 -0
- package/dist/src/validation/validators/verify-card-params-validator.js +18 -0
- package/dist/src/validation/validators/verify-card-params-validator.js.map +1 -0
- package/dist/tests/helpers/api-gateway-mock.js +36 -0
- package/dist/tests/helpers/api-gateway-mock.js.map +1 -0
- package/dist/validation/index.d.ts +3 -0
- package/dist/validation/index.js +3 -0
- package/dist/validation/schemas/customer.json +38 -0
- package/dist/validation/schemas/hpp-load-params.json +40 -0
- package/dist/validation/schemas/hpp-options.json +48 -0
- package/dist/validation/schemas/payment-intent.json +48 -0
- package/dist/validation/schemas/payment-method.json +83 -0
- package/dist/validation/schemas/verify-card-options.json +15 -0
- package/dist/validation/schemas/verify-card-params.json +24 -0
- package/dist/validation/validation-helper.d.ts +3 -0
- package/dist/validation/validation-helper.js +6 -0
- package/dist/validation/validators/hpp-load-params-validator.d.ts +3 -0
- package/dist/validation/validators/hpp-load-params-validator.js +14 -0
- package/dist/validation/validators/verify-card-params-validator.d.ts +3 -0
- package/dist/validation/validators/verify-card-params-validator.js +16 -0
- package/docker-compose.yml +16 -0
- package/package.json +44 -13
- package/tsconfig.json +8 -18
- package/tsconfig.package.json +25 -0
- package/fat-zebra-sdk-1.0.2.tgz +0 -0
- package/fatzebra-sdk-1.0.0.tgz +0 -0
- package/index.js +0 -0
- package/jest.config.js +0 -16
- package/yarn-error.log +0 -2374
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<title>Merchant XYZ Checkout Page</title>
|
|
6
|
+
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
|
7
|
+
<style type="text/css">
|
|
8
|
+
iframe {
|
|
9
|
+
height: 600px;
|
|
10
|
+
width: 700px;
|
|
11
|
+
}
|
|
12
|
+
</style>
|
|
13
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
|
14
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-md5.js"></script>
|
|
15
|
+
<script>
|
|
16
|
+
window.localStorage.setItem('fz-access-token', "<DO NOT USE>")
|
|
17
|
+
// card tokens will be filled out
|
|
18
|
+
var actionItems = {
|
|
19
|
+
tokens: [
|
|
20
|
+
{
|
|
21
|
+
token: 'whatever',
|
|
22
|
+
number: '4000000000001000',
|
|
23
|
+
description: 'Successful Frictionless Authentication'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
token: '',
|
|
27
|
+
number: '4000000000001026',
|
|
28
|
+
description: 'Attempts Stand-In Frictionless'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
token: '',
|
|
32
|
+
number: '4000000000001034',
|
|
33
|
+
description: 'Unavailable Frictionless'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
token: '',
|
|
37
|
+
number: '4000000000001059',
|
|
38
|
+
description: 'Authentication Not Available on Lookup'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
token: '',
|
|
42
|
+
number: '4000000000001067',
|
|
43
|
+
description: 'Error on Lookup'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
token: '',
|
|
47
|
+
number: '4000000000001075',
|
|
48
|
+
description: 'Timeout on cmpi_lookup'
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
token: '',
|
|
52
|
+
number: '4000000000001083',
|
|
53
|
+
description: 'Bypassed Authentication'
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
token: '',
|
|
57
|
+
number: '4000000000001018',
|
|
58
|
+
description: 'Failed Frictionless'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
token: '',
|
|
62
|
+
number: '4000000000001042',
|
|
63
|
+
description: 'Rejected Frictionless'
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
token: 'ahq94qb60fs0xaruga3h',
|
|
67
|
+
number: '4000000000001091',
|
|
68
|
+
description: 'Challenge'
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
cards: [
|
|
72
|
+
{
|
|
73
|
+
number: '4000000000001000',
|
|
74
|
+
description: 'Successful Frictionless Authentication'
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
number: '4000000000001026',
|
|
78
|
+
description: 'Attempts Stand-In Frictionless'
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
number: '4000000000001034',
|
|
82
|
+
description: 'Unavailable Frictionless'
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
number: '4000000000001059',
|
|
86
|
+
description: 'Authentication Not Available on Lookup'
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
number: '4000000000001067',
|
|
90
|
+
description: 'Error on Lookup'
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
number: '4000000000001075',
|
|
94
|
+
description: 'Timeout on cmpi_lookup'
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
number: '4000000000001083',
|
|
98
|
+
description: 'Bypassed Authentication'
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
number: '4000000000001018',
|
|
102
|
+
description: 'Failed Frictionless'
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
number: '4000000000001042',
|
|
106
|
+
description: 'Rejected Frictionless'
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
number: '4000000000001091',
|
|
110
|
+
description: 'Challenge'
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
</script>
|
|
115
|
+
<script src="fatzebra.js"></script></head>
|
|
116
|
+
<body>
|
|
117
|
+
<table id="options" class="table table-bordered">
|
|
118
|
+
<thead>
|
|
119
|
+
<tr>
|
|
120
|
+
<th scope="col">Card Token</th>
|
|
121
|
+
<th scope="col">New Card</th>
|
|
122
|
+
<th scope="col">Description</th>
|
|
123
|
+
</tr>
|
|
124
|
+
</thead>
|
|
125
|
+
<tbody>
|
|
126
|
+
</tbody>
|
|
127
|
+
</table>
|
|
128
|
+
<button type="button" class="btn btn-primary" id='doCheckout'>Primary</button>
|
|
129
|
+
|
|
130
|
+
<script>
|
|
131
|
+
var selectedMode = undefined
|
|
132
|
+
var selectedValue = undefined
|
|
133
|
+
|
|
134
|
+
$(document).ready(function() {
|
|
135
|
+
|
|
136
|
+
for (var i = 0; i < actionItems.tokens.length; i ++ ) {
|
|
137
|
+
const row = "<tr><td><input type='checkbox' class='option' data-mode='token' value='" + actionItems.tokens[i].token + "'><label>token for " + actionItems.tokens[i].number + "</label></td>" +
|
|
138
|
+
"<td><input type='checkbox' class='option' data-mode='card' value='" + actionItems.cards[i].number + "'><label>" + actionItems.cards[i].number + "</label></td>" +
|
|
139
|
+
"<td><label>" + actionItems.cards[i].description + "</label></td></tr>";
|
|
140
|
+
$('#options').append(row)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
$('.option').change(function() {
|
|
144
|
+
|
|
145
|
+
if ($(this).prop("checked") == true) {
|
|
146
|
+
if (selectedValue === undefined) {
|
|
147
|
+
selectedMode = $(this).data('mode');
|
|
148
|
+
selectedValue = $(this).val();
|
|
149
|
+
} else {
|
|
150
|
+
$(this).prop("checked", false)
|
|
151
|
+
alert("There can only be one checkbox selected!");
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
selectedMode = undefined;
|
|
155
|
+
selectedValue = undefined;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
console.log('selectedMode: ' + selectedMode);
|
|
159
|
+
console.log('selectedValue: ' + selectedValue);
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
</script>
|
|
164
|
+
</body>
|
|
165
|
+
<footer>
|
|
166
|
+
|
|
167
|
+
<script>
|
|
168
|
+
var fz = new FatZebra({
|
|
169
|
+
username: 'TEST'
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
$('#doCheckout').click(function() {
|
|
173
|
+
if (selectedMode === undefined || selectedValue == undefined) {
|
|
174
|
+
alert('Please select an option.');
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
var paymentMethod = undefined;
|
|
179
|
+
|
|
180
|
+
if (selectedMode === 'card') {
|
|
181
|
+
paymentMethod = {
|
|
182
|
+
type: 'card',
|
|
183
|
+
data: {
|
|
184
|
+
number: selectedValue,
|
|
185
|
+
holder: 'John Doe',
|
|
186
|
+
expiryMonth: '01',
|
|
187
|
+
expiryYear: '2022',
|
|
188
|
+
cvv: '123'
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
paymentMethod = {
|
|
193
|
+
type: 'card_on_file',
|
|
194
|
+
data: {
|
|
195
|
+
token: selectedValue
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function randomString(length) {
|
|
201
|
+
return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const reference = randomString(16);
|
|
205
|
+
const amount = 1200000;
|
|
206
|
+
const currency = 'AUD';
|
|
207
|
+
const message = [reference, amount, currency].join(':')
|
|
208
|
+
const verification = CryptoJS.HmacMD5(message, "033bd94b11").toString();
|
|
209
|
+
|
|
210
|
+
fz.verifyCard({
|
|
211
|
+
customer: {
|
|
212
|
+
firstName: 'Captain',
|
|
213
|
+
lastName: 'America',
|
|
214
|
+
email: 'sos@fatzebra.com.au',
|
|
215
|
+
address: '123 Get High Blvd.',
|
|
216
|
+
city: 'Red Light District',
|
|
217
|
+
postcode: '6666',
|
|
218
|
+
state: 'NSW',
|
|
219
|
+
country: 'Australia'
|
|
220
|
+
},
|
|
221
|
+
paymentIntent: {
|
|
222
|
+
payment: {
|
|
223
|
+
amount: amount,
|
|
224
|
+
currency: currency,
|
|
225
|
+
reference: reference
|
|
226
|
+
},
|
|
227
|
+
verification: verification
|
|
228
|
+
},
|
|
229
|
+
paymentMethod: paymentMethod
|
|
230
|
+
})
|
|
231
|
+
})
|
|
232
|
+
|
|
233
|
+
fz.on('fz.sca.error', function(event) {
|
|
234
|
+
console.log(JSON.stringify(event.detail))
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
fz.on('fz.sca.success', function(event) {
|
|
238
|
+
console.log(JSON.stringify(event.detail))
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
fz.on('fz.validation.error', function(event) {
|
|
242
|
+
console.log(JSON.stringify(event.detail))
|
|
243
|
+
})
|
|
244
|
+
</script>
|
|
245
|
+
|
|
246
|
+
</footer>
|
|
247
|
+
</html>
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Customer, PaymentIntent, PaymentMethod, PublicEvent } from './shared/types';
|
|
2
|
+
import { HppLoadParams } from './hpp';
|
|
3
|
+
import { PayPalConfig } from './paypal/types';
|
|
4
|
+
import { ChallengeWindowSize } from './sca/types';
|
|
5
|
+
export interface FZConfig {
|
|
6
|
+
username: string;
|
|
7
|
+
test?: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface Card {
|
|
10
|
+
number: string;
|
|
11
|
+
holder: string;
|
|
12
|
+
expiryMonth: string;
|
|
13
|
+
expiryYear: string;
|
|
14
|
+
cvv: string;
|
|
15
|
+
}
|
|
16
|
+
interface VerifyCardParams {
|
|
17
|
+
customer: Customer;
|
|
18
|
+
paymentIntent: PaymentIntent;
|
|
19
|
+
paymentMethod: PaymentMethod;
|
|
20
|
+
options?: VerifyCardOptions;
|
|
21
|
+
}
|
|
22
|
+
interface VerifyCardOptions {
|
|
23
|
+
challengeWindowSize?: ChallengeWindowSize;
|
|
24
|
+
}
|
|
25
|
+
export default class FatZebra {
|
|
26
|
+
private sca;
|
|
27
|
+
private fzConfig;
|
|
28
|
+
private gatewayClient;
|
|
29
|
+
constructor(config: FZConfig);
|
|
30
|
+
tokenizeCard(card: Card, headless: HTMLIFrameElement): void;
|
|
31
|
+
cardDidTokenize(headless: HTMLIFrameElement, callback: (data: any) => void): void;
|
|
32
|
+
verifyCard(params: VerifyCardParams): Promise<void>;
|
|
33
|
+
renderPaymentsPage(params: HppLoadParams): void;
|
|
34
|
+
checkout(): void;
|
|
35
|
+
setupPayPal(config: PayPalConfig): void;
|
|
36
|
+
on(event: PublicEvent, callback: (e: any) => void): void;
|
|
37
|
+
}
|
|
38
|
+
export { type HppLoadParams, FatZebra, };
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import Sca from './sca';
|
|
11
|
+
import { PostMessageClient, } from './shared/post-message-client';
|
|
12
|
+
import { BridgeEvent, PaymentMethodType, PublicEvent, } from './shared/types';
|
|
13
|
+
import { LocalStorageAccessTokenKey } from './shared/constants';
|
|
14
|
+
import { emit, on } from './shared/event-manager';
|
|
15
|
+
import * as bridge from './shared/bridge-client';
|
|
16
|
+
import { validateHppLoadParams, validateVerifyCardParams, toHumanizedErrors, } from './validation';
|
|
17
|
+
import GatewayClient from './shared/api-gateway-client';
|
|
18
|
+
import { Hpp } from './hpp';
|
|
19
|
+
import { PayPalCheckout } from './paypal/paypal-checkout';
|
|
20
|
+
export default class FatZebra {
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.fzConfig = config;
|
|
23
|
+
window.MerchantUsername = config.username;
|
|
24
|
+
this.gatewayClient = new GatewayClient({
|
|
25
|
+
accessToken: window.localStorage.getItem(LocalStorageAccessTokenKey),
|
|
26
|
+
username: config.username,
|
|
27
|
+
});
|
|
28
|
+
this.sca = new Sca({
|
|
29
|
+
gatewayClient: this.gatewayClient,
|
|
30
|
+
});
|
|
31
|
+
this.sca.loadScript();
|
|
32
|
+
}
|
|
33
|
+
tokenizeCard(card, headless) {
|
|
34
|
+
const channel = 'sca';
|
|
35
|
+
headless.onload = () => {
|
|
36
|
+
const message = {
|
|
37
|
+
channel,
|
|
38
|
+
subject: BridgeEvent.TOKENIZE_CARD_REQUEST,
|
|
39
|
+
data: {
|
|
40
|
+
access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
|
|
41
|
+
card_holder: card.holder,
|
|
42
|
+
card_number: card.number,
|
|
43
|
+
card_expiry: `${card.expiryMonth}/${card.expiryYear}`,
|
|
44
|
+
cvv: card.cvv,
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
headless.contentWindow.postMessage(message, '*');
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
cardDidTokenize(headless, callback) {
|
|
51
|
+
const channel = 'sca';
|
|
52
|
+
const postMessageClient = new PostMessageClient({
|
|
53
|
+
channel,
|
|
54
|
+
target: headless
|
|
55
|
+
});
|
|
56
|
+
const handlers = {};
|
|
57
|
+
handlers[BridgeEvent.TOKENIZE_CARD_RESPONSE] = (data) => {
|
|
58
|
+
callback(data);
|
|
59
|
+
};
|
|
60
|
+
postMessageClient.setEventListeners(handlers);
|
|
61
|
+
}
|
|
62
|
+
verifyCard(params) {
|
|
63
|
+
var _a;
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
const valid = validateVerifyCardParams(params);
|
|
66
|
+
if (!valid) {
|
|
67
|
+
emit(PublicEvent.VALIDATION_ERROR, {
|
|
68
|
+
errors: toHumanizedErrors(validateVerifyCardParams.errors),
|
|
69
|
+
data: null
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
switch (params.paymentMethod.type) {
|
|
74
|
+
case PaymentMethodType.CARD:
|
|
75
|
+
const headless = bridge.load(process.env.PAYNOW_BRIDGE_URL);
|
|
76
|
+
const card = params.paymentMethod.data;
|
|
77
|
+
this.cardDidTokenize(headless, (data) => __awaiter(this, void 0, void 0, function* () {
|
|
78
|
+
var _b;
|
|
79
|
+
const bin = card.number.substr(0, 6);
|
|
80
|
+
this.sca.run({
|
|
81
|
+
cardToken: data.token,
|
|
82
|
+
customer: params.customer,
|
|
83
|
+
paymentIntent: params.paymentIntent,
|
|
84
|
+
bin,
|
|
85
|
+
challengeWindowSize: (_b = params.options) === null || _b === void 0 ? void 0 : _b.challengeWindowSize,
|
|
86
|
+
});
|
|
87
|
+
}));
|
|
88
|
+
this.tokenizeCard(card, headless);
|
|
89
|
+
break;
|
|
90
|
+
case PaymentMethodType.CARD_ON_FILE:
|
|
91
|
+
const cardToken = params.paymentMethod.data.token;
|
|
92
|
+
const bin = (yield this.gatewayClient.getCard({ card_token: cardToken })).data.bin;
|
|
93
|
+
this.sca.run({
|
|
94
|
+
cardToken,
|
|
95
|
+
customer: params.customer,
|
|
96
|
+
paymentIntent: params.paymentIntent,
|
|
97
|
+
bin,
|
|
98
|
+
challengeWindowSize: (_a = params.options) === null || _a === void 0 ? void 0 : _a.challengeWindowSize,
|
|
99
|
+
});
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
renderPaymentsPage(params) {
|
|
105
|
+
const valid = validateHppLoadParams(params);
|
|
106
|
+
if (!valid) {
|
|
107
|
+
emit(PublicEvent.VALIDATION_ERROR, {
|
|
108
|
+
errors: toHumanizedErrors(validateHppLoadParams.errors),
|
|
109
|
+
data: null
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
window.HPP = new Hpp({
|
|
114
|
+
version: params.version,
|
|
115
|
+
paymentIntent: params.paymentIntent,
|
|
116
|
+
customer: params.customer,
|
|
117
|
+
username: this.fzConfig.username,
|
|
118
|
+
sca: this.sca,
|
|
119
|
+
test: this.fzConfig.test,
|
|
120
|
+
});
|
|
121
|
+
window.HPP.load(params);
|
|
122
|
+
}
|
|
123
|
+
checkout() {
|
|
124
|
+
window.HPP.purchase();
|
|
125
|
+
}
|
|
126
|
+
setupPayPal(config) {
|
|
127
|
+
const paypalCheckout = new PayPalCheckout({
|
|
128
|
+
currency: config.currency,
|
|
129
|
+
payment: config.payment,
|
|
130
|
+
containerId: config.containerId,
|
|
131
|
+
style: config.style
|
|
132
|
+
});
|
|
133
|
+
paypalCheckout.load()
|
|
134
|
+
.then(function () {
|
|
135
|
+
paypalCheckout.render();
|
|
136
|
+
})
|
|
137
|
+
.catch(function (error) {
|
|
138
|
+
emit(PublicEvent.PAYPAL_ERROR, {
|
|
139
|
+
errors: [error].flat(),
|
|
140
|
+
data: null
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
on(event, callback) {
|
|
145
|
+
on(event, callback);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
export { FatZebra, };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { PayPalPaymentMethod } from './types';
|
|
2
|
+
import { PaymentIntent } from '../shared/types';
|
|
3
|
+
interface PayPal {
|
|
4
|
+
render(containerId: string): void;
|
|
5
|
+
}
|
|
6
|
+
interface PayPalButtonStyle {
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}
|
|
9
|
+
export default class PayPalButton {
|
|
10
|
+
private validationErrorRaised;
|
|
11
|
+
private _paypalButtons;
|
|
12
|
+
private paymentMethod;
|
|
13
|
+
private paymentIntent;
|
|
14
|
+
private buttonStyle;
|
|
15
|
+
private billingAgreement;
|
|
16
|
+
private client;
|
|
17
|
+
private actions;
|
|
18
|
+
constructor(paymentMethod?: PayPalPaymentMethod, paymentIntent?: PaymentIntent, billingAgreement?: boolean, buttonStyle?: PayPalButtonStyle);
|
|
19
|
+
get paypalButtons(): any;
|
|
20
|
+
get paypalActions(): any;
|
|
21
|
+
render(containerId: string): void;
|
|
22
|
+
getContainer(containerId: string): any;
|
|
23
|
+
private createButton;
|
|
24
|
+
private createOrder;
|
|
25
|
+
private approveOrder;
|
|
26
|
+
private createBillingAgreement;
|
|
27
|
+
private approveBillingAgreement;
|
|
28
|
+
private formatError;
|
|
29
|
+
}
|
|
30
|
+
export { PayPalButton };
|
|
31
|
+
export type { PayPal, PayPalButtonStyle, };
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { emit } from '../shared/event-manager';
|
|
11
|
+
import { PayPalIntent } from './types';
|
|
12
|
+
import GatewayClient from '../shared/api-gateway-client';
|
|
13
|
+
import { PublicEvent } from '../shared/types';
|
|
14
|
+
import * as util from '../shared/util';
|
|
15
|
+
import { LocalStorageAccessTokenKey } from '../shared/constants';
|
|
16
|
+
const defaultStyle = {
|
|
17
|
+
layout: 'horizontal',
|
|
18
|
+
color: 'gold',
|
|
19
|
+
shape: 'pill',
|
|
20
|
+
label: 'paypal',
|
|
21
|
+
};
|
|
22
|
+
export default class PayPalButton {
|
|
23
|
+
constructor(paymentMethod, paymentIntent, billingAgreement, buttonStyle) {
|
|
24
|
+
this.paymentMethod = paymentMethod;
|
|
25
|
+
this.paymentIntent = paymentIntent;
|
|
26
|
+
this.billingAgreement = billingAgreement;
|
|
27
|
+
this.buttonStyle = buttonStyle;
|
|
28
|
+
this.client = new GatewayClient({ accessToken: window.localStorage.getItem(LocalStorageAccessTokenKey),
|
|
29
|
+
username: window.MerchantUsername,
|
|
30
|
+
});
|
|
31
|
+
this.createButton();
|
|
32
|
+
}
|
|
33
|
+
get paypalButtons() {
|
|
34
|
+
return this._paypalButtons;
|
|
35
|
+
}
|
|
36
|
+
get paypalActions() {
|
|
37
|
+
return this.actions;
|
|
38
|
+
}
|
|
39
|
+
render(containerId) {
|
|
40
|
+
let container = this.getContainer(containerId);
|
|
41
|
+
if (typeof (container) != 'undefined' && container != null) {
|
|
42
|
+
this._paypalButtons.render('#' + container.id);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
emit(PublicEvent.PAYPAL_ERROR, {
|
|
46
|
+
errors: [`Container with id #${containerId} does not exist.`],
|
|
47
|
+
data: null
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
getContainer(containerId) {
|
|
52
|
+
return document.getElementById(containerId);
|
|
53
|
+
}
|
|
54
|
+
createButton() {
|
|
55
|
+
let button = ({});
|
|
56
|
+
button.style = (this.buttonStyle ? this.buttonStyle : defaultStyle);
|
|
57
|
+
if (this.billingAgreement === true) {
|
|
58
|
+
button.createBillingAgreement = () => __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
return this.createBillingAgreement();
|
|
60
|
+
});
|
|
61
|
+
button.onApprove = (data, actions) => __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
emit(PublicEvent.PAYPAL_PROCESSESING, { data: {}, message: 'The request is being processed.' });
|
|
63
|
+
return this.approveBillingAgreement(data);
|
|
64
|
+
});
|
|
65
|
+
button.onCancel = (data, actions) => {
|
|
66
|
+
emit(PublicEvent.PAYPAL_CANCEL, { data: { id: data.orderID }, message: 'PayPal Billing Agreement cancelled.' });
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
button.createOrder = () => __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
return this.createOrder();
|
|
72
|
+
});
|
|
73
|
+
button.onApprove = (data, actions) => __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
emit(PublicEvent.PAYPAL_PROCESSESING, { data: {}, message: 'The request is being processed.' });
|
|
75
|
+
return this.approveOrder(data);
|
|
76
|
+
});
|
|
77
|
+
button.onCancel = (data, actions) => {
|
|
78
|
+
emit(PublicEvent.PAYPAL_CANCEL, { data: { id: data.orderID }, message: 'PayPal Order cancelled.' });
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
button.onError = (error) => {
|
|
82
|
+
// This flag is used to prevent emitting general error from PayPal
|
|
83
|
+
// if an error has already been raised and emitted.
|
|
84
|
+
if (this.validationErrorRaised === false) {
|
|
85
|
+
emit(PublicEvent.PAYPAL_ERROR, {
|
|
86
|
+
errors: ['PayPal Checkout failed.'],
|
|
87
|
+
data: null
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
this._paypalButtons = window.paypal.Buttons(button);
|
|
92
|
+
}
|
|
93
|
+
createOrder() {
|
|
94
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
try {
|
|
96
|
+
this.validationErrorRaised = false;
|
|
97
|
+
let payload = util.toObjectWithSnakeCaseKeys(this.paymentMethod);
|
|
98
|
+
payload.payment_intent = this.paymentIntent;
|
|
99
|
+
const response = (yield this.client.createPayPalOrder({
|
|
100
|
+
order: payload
|
|
101
|
+
})).data;
|
|
102
|
+
return response.id;
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
this.validationErrorRaised = true;
|
|
106
|
+
emit(PublicEvent.PAYPAL_ERROR, {
|
|
107
|
+
errors: this.formatError(error),
|
|
108
|
+
data: null
|
|
109
|
+
});
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
approveOrder(data) {
|
|
115
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
116
|
+
try {
|
|
117
|
+
this.validationErrorRaised = false;
|
|
118
|
+
let response = undefined;
|
|
119
|
+
if (this.paymentMethod.intent.toUpperCase() === PayPalIntent.CAPTURE) {
|
|
120
|
+
response = (yield this.client.capturePayPalOrder({
|
|
121
|
+
id: data.orderID
|
|
122
|
+
})).data;
|
|
123
|
+
}
|
|
124
|
+
else if (this.paymentMethod.intent.toUpperCase() === PayPalIntent.AUTHORIZE) {
|
|
125
|
+
response = (yield this.client.authorizePayPalOrder({
|
|
126
|
+
id: data.orderID
|
|
127
|
+
})).data;
|
|
128
|
+
}
|
|
129
|
+
emit(PublicEvent.PAYPAL_SUCCESS, {
|
|
130
|
+
data: util.toObjectWithCamelCaseKeys(response),
|
|
131
|
+
message: 'PayPal order approved.'
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
this.validationErrorRaised = true;
|
|
137
|
+
emit(PublicEvent.PAYPAL_ERROR, {
|
|
138
|
+
errors: this.formatError(error),
|
|
139
|
+
data: null
|
|
140
|
+
});
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
createBillingAgreement() {
|
|
146
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
147
|
+
try {
|
|
148
|
+
this.validationErrorRaised = false;
|
|
149
|
+
let payload = util.toObjectWithSnakeCaseKeys(this.paymentMethod);
|
|
150
|
+
delete payload.billing_agreement;
|
|
151
|
+
let response = (yield this.client.createPayPalBillingAgreement({
|
|
152
|
+
billing: payload
|
|
153
|
+
})).data;
|
|
154
|
+
return response.token_id;
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
this.validationErrorRaised = true;
|
|
158
|
+
emit(PublicEvent.PAYPAL_ERROR, {
|
|
159
|
+
errors: this.formatError(error),
|
|
160
|
+
data: null
|
|
161
|
+
});
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
approveBillingAgreement(data) {
|
|
167
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
168
|
+
try {
|
|
169
|
+
this.validationErrorRaised = false;
|
|
170
|
+
let response = (yield this.client.approvePayPalBillingAgreement({
|
|
171
|
+
id: data.billingToken
|
|
172
|
+
})).data;
|
|
173
|
+
emit(PublicEvent.PAYPAL_SUCCESS, {
|
|
174
|
+
data: util.toObjectWithCamelCaseKeys(response),
|
|
175
|
+
message: 'PayPal Billing Agreement created.'
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
this.validationErrorRaised = true;
|
|
181
|
+
emit(PublicEvent.PAYPAL_ERROR, {
|
|
182
|
+
errors: this.formatError(error),
|
|
183
|
+
data: null
|
|
184
|
+
});
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
formatError(error) {
|
|
190
|
+
var _a, _b;
|
|
191
|
+
var message = [(_b = (_a = error === null || error === void 0 ? void 0 : error.request) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.errors].flat();
|
|
192
|
+
if (typeof message[0] === 'undefined')
|
|
193
|
+
message = [error === null || error === void 0 ? void 0 : error.message].flat();
|
|
194
|
+
if (typeof message[0] === 'undefined')
|
|
195
|
+
message = ['Unknown error'];
|
|
196
|
+
return message;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
export { PayPalButton };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PayPalButton } from './paypal-button';
|
|
2
|
+
import { PayPalConfig } from './types';
|
|
3
|
+
export default class PayPalCheckout {
|
|
4
|
+
private paypalButton;
|
|
5
|
+
private validationErrors;
|
|
6
|
+
private intent;
|
|
7
|
+
private currency;
|
|
8
|
+
private payment;
|
|
9
|
+
private billingAgreement;
|
|
10
|
+
private containerId;
|
|
11
|
+
private buttonStyle;
|
|
12
|
+
constructor(config: PayPalConfig);
|
|
13
|
+
get paypal(): PayPalButton;
|
|
14
|
+
set paypal(paypal: PayPalButton);
|
|
15
|
+
load(): Promise<any>;
|
|
16
|
+
render(): void;
|
|
17
|
+
private validatePayPalSetup;
|
|
18
|
+
private validatePayPalRequest;
|
|
19
|
+
private errors;
|
|
20
|
+
}
|
|
21
|
+
export { PayPalCheckout };
|