├── .gitignore
├── Gruntfile.js
├── LEEME.md
├── LICENSE
├── README.md
├── lib
├── openpay-data.v1.js
├── openpay-data.v1.min.js
├── openpay.v1.js
└── openpay.v1.min.js
├── package.json
└── test
├── openpay_data_js_test.html
└── openpay_js_test.html
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function(grunt) {
2 |
3 | // Project configuration.
4 | grunt.initConfig({
5 | pkg: grunt.file.readJSON('package.json'),
6 | uglify: {
7 | options : {
8 | ie8 : true,
9 | output : {
10 | ascii_only : true
11 | }
12 | },
13 | openpayJs: {
14 | src: 'lib/openpay.v1.js',
15 | dest: 'lib/openpay.v1.min.js',
16 | options : {
17 | banner: '/*! openpay.js v<%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd") %> */'
18 | }
19 | },
20 | openpayData: {
21 | src: 'lib/openpay-data.v1.js',
22 | dest: 'lib/openpay-data.v1.min.js',
23 | options : {
24 | banner: '/*! openpay-data.js v<%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd") %> */'
25 | }
26 | }
27 | }
28 | });
29 |
30 | grunt.loadNpmTasks('grunt-contrib-uglify');
31 |
32 | };
--------------------------------------------------------------------------------
/LEEME.md:
--------------------------------------------------------------------------------
1 | #Openpay.js
2 |
3 | [Documentacion en español](http://docs.openpay.mx/#openpay-js)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | ## Introduction
4 | ### What is Openpay.js?
5 | Openpay.js is a Javascript library designed to makes it easy to collect credit card data without having the information touch your server.
6 |
7 | ### Benefits:
8 | * The transaction information does not have to pass through your server, it is sent directly to Openpay.
9 | * It is the easiest and fastest way to integrate a charges module on your ecommerce website.
10 |
11 | ## Getting started
12 | The first step in the integration is to add the library to the page from which payments will be made. Add the following script tag:
13 | ```HTML
14 |
15 | ```
16 | ### Configuration
17 | Before you can use Openpay.js is necessary to configure both the merchant id, and public key that were assigned when you created your [OpenPay account](https://sandbox-dashboard.openpay.mx/login). With these data, Openpay can identify the account to which the charges are paid.
18 |
19 | You can configure both fields with the following methods **OpenPay.setId()** and **OpenPay.setApiKey()**, respectively:
20 | ```javascript
21 | OpenPay.setId('MERCHANT_ID');
22 | OpenPay.setApiKey('PUBLIC_API_KEY');
23 | ```
24 | |Notes: |
25 | |:--------------------------------------------------------------------------------------------------------|
26 | |* Both **MERCHANT_ID** as **PUBLIC_API_KEY**, are obtained from the homepage of your OpenPay account. |
27 | |* You should never use your private key along with the library, because it is visible on the client side.|
28 |
29 | ### Enable sandbox Mode
30 | To test your implementation, there Sandox environment, which is enabled with the method: **OpenPay.setSandboxMode()**
31 | ```javascript
32 | OpenPay.setSandboxMode(FLAG);
33 | ```
34 | The FLAG parameter is a true / false flag to enable or disable test mode.
35 |
36 | If is necessary, you can use the **OpenPay.getSandboxMode()** method to determine the status of the Sandbox Mode at any time:
37 | ```javascript
38 | OpenPay.getSandboxMode(); // TRUE/FALSE, depends if is activated or not activated.
39 | ```
40 | |Notes: |
41 | |:-------------------------------------------------------------------------------------------------------------|
42 | |* The sandbox environment has the same features as production, but only allows the use of certain card |
43 | |numbers, chosen so that you can test, more information on the [test section](http://docs.openpay.mx/#pruebas).|
44 |
45 | ## Creating tokens
46 | Once you installed and configured the library, to create a token is necessary call the method: **OpenPay.token.create()**
47 | ```javascript
48 | OpenPay.token.create(CREATE_PARAMETERS_OBJECT, SUCCESS_CALLBACK, ERROR_CALLBACK);
49 | ```
50 | The method's params are:
51 | * The **CREATE_PARAMETERS_OBJECT** parameter is an javascript object with credit card information.
52 | * The **SUCCESS_CALLBACK** parameter define the callback method which will be called when the operation is correct.
53 | * The **ERROR_CALLBACK** parameter define the callback method which will be called when the operation has failed.
54 |
55 | The method returns an object token. The definition of object token find it [here](http://docs.openpay.mx/#tokens).
56 |
57 | #### Example of creating a token card:
58 |
59 | ```javascript
60 | OpenPay.token.create({
61 | "card_number":"4111111111111111",
62 | "holder_name":"Juan Perez Ramirez",
63 | "expiration_year":"20",
64 | "expiration_month":"12",
65 | "cvv2":"110",
66 | "address":{
67 | "city":"Querétaro",
68 | "line3":"Queretaro",
69 | "postal_code":"76900",
70 | "line1":"Av 5 de Febrero",
71 | "line2":"Roble 207",
72 | "state":"Queretaro",
73 | "country_code":"MX"
74 | }
75 | }, onSuccess, onError);
76 | ```
77 |
78 | ## Creating tokens from html form
79 | The Openpay.js library provides you extraction of the card information from the html form and subsequent delivery by the method:
80 | **OpenPay.token.extractFormAndCreate()**
81 | ```javascript
82 | OpenPay.token.extractFormAndCreate(CREATE_FORM_OBJECT, SUCCESS_CALLBACK, ERROR_CALLBACK, {CLIENTE-ID});
83 | ```
84 | The method's params are:
85 | * The **CREATE_PARAMETERS_OBJECT** parameter is an javascript object with credit card information.
86 | * The **SUCCESS_CALLBACK** parameter define the callback method which will be called when the operation is correct.
87 | * The **ERROR_CALLBACK** parameter define the callback method which will be called when the operation has failed.
88 |
89 | To begin to create tokens, you need a html form like this:
90 |
91 | ```html
92 |
107 | ```
108 | Note: The more important thing is add data-attributes **data-openpay-card** and **data-card-data-openpay-address** on inputs where card information is captured and address respectively.
109 |
110 | Later when generating the token, make an invocation to **OpenPay.token.extractFormAndCreate()**, as show below:
111 | ```javascript
112 | OpenPay.token.extractFormAndCreate(
113 | $('#processCard'),
114 | successCard,
115 | errorCard,
116 | _customerId);
117 | ```
118 |
119 | The method returns an object type token. The definition of object token find it [here](http://docs.openpay.mx/#tokens).
120 |
121 | For a complete example, download the test from the github site:[openpay.js](https://github.com/open-pay/openpay-js)
122 |
123 | ## Updating Cards
124 |
125 | Openpay.js allows you to update card information of stored customer cards. This is useful in order to avoid sending this information to your back-end for updating.
126 |
127 | The data that can be updated is: Holder name, expiration date, and expiration year. In addition, the API allows to send a CVV that will be used in the next charge with this card.
128 | The method used for this is:
129 | **OpenPay.card.update()**
130 | ```javascript
131 | OpenPay.card.update(UPDATE_CARD_OBJECT, SUCCESS_CALLBACK, ERROR_CALLBACK, {CLIENTE-ID}, CARD_ID);
132 | ```
133 |
134 | You can find the definition of the UPDATE_CARD_OBJECT [here](http://docs.openpay.mx/#actualizar-c-digo-de-seguridad-de-tarjeta)
135 |
136 | ## Creating Group Tokens
137 | If your Merchant account is part of a group of merchants, you can use the library to create shared group tokens. To do so, you must first configure
138 | your group credentials:
139 |
140 | ```javascript
141 | OpenPay.Group.setId('GROUP_ID');
142 | OpenPay.Group.setApiKey('PUBLIC_API_KEY');
143 | ```
144 |
145 | You can then use the following methods in the same way as with regular tokens:
146 |
147 | ```javascript
148 | OpenPay.Group.token.create(CREATE_PARAMETERS_OBJECT, SUCCESS_CALLBACK, ERROR_CALLBACK);
149 |
150 | OpenPay.Group.token.extractFormAndCreate(CREATE_FORM_OBJECT, SUCCESS_CALLBACK, ERROR_CALLBACK, {CLIENTE-ID});
151 | ```
152 |
153 | ## How to handle responses
154 | The response functions serve as handles of the result of the transaction. These, are simple Javascript functions but receive and object type response.
155 |
156 | The response object fields are described below:
157 |
158 | |Field|Format|Description|
159 | | -------- | --------- | --------- |
160 | |status|Integer|Describe the HTTP status of the transaction. If an error before sending the request occurs, the status will be zero. In case of success the response will be 200|
161 | |message|String|Only occurs in cases of error. Short description of the error that occurred. It can be one of the following values: "Unknown error", "Request error", "Response error (end Unknown status)", "Empty or invalid OpenPay ID", "Empty or invalid API Key", "Browser error", "timeout after X milliseconds ".|
162 | |data|Objeto|Contains an [Object Error](http://docs.openpay.mx/ # errors) with the error information in the transaction provided by the server OpenPay. On success contains a token type object.|
163 |
164 |
165 | | Notes |
166 | | :------------- |
167 | |* Although the response functions are optional, we recommend to implement the outcome of the transaction can be monitored on the website.|
168 |
169 | ### On success: SuccessCallback
170 | This function is called when the operation is successful from start to finish. It receives a single parameter which is a Javascript object with a data property representing a [card](http://docs.openpay.mx/#tarjetas) or a [token](http://docs.openpay.mx/#tokens) object.
171 | Complete example of implementing a function SuccessCallback:
172 | ```javascript
173 | function SuccessCallback(response) {
174 | alert('Successful operation');
175 | var content = '', results = document.getElementById('resultDetail');
176 | content .= 'Id card: ' + response.data.id+ ' ';
177 | content .= 'Holder Name: ' + response.data.holder_name + ' ';
178 | content .= 'Card brand: ' + response.data.brand + ' ';
179 | results.innerHTML = content;
180 | }
181 | }
182 | ```
183 |
184 | ### In case of error: ErrorCallback
185 | This function will be executed each time an operation has failed (for any reason, before or after sending the request). Like the method **SuccessCallback()**, takes a single parameter which is a Javascript object with detailed fault.
186 |
187 | Complete example of implementing a function ErrorCallback:
188 | ```javascript
189 | function ErrorCallback(response) {
190 | alert('Fallo en la transacción');
191 | var content = '', results = document.getElementById('resultDetail');
192 | content .= 'Estatus del error: ' + response.data.status + ' ';
193 | content .= 'Error: ' + response.message + ' ';
194 | content .= 'Descripción: ' + response.data.description + ' ';
195 | content .= 'ID de la petición: ' + response.data.request_id + ' ';
196 | results.innerHTML = content;
197 | }
198 | ```
199 |
200 | ### Types error responses
201 | In addition to the status field that saves the state of the transaction, it is possible to determine the error that happened through the message field. The message may be one of the following:
202 |
203 | * **"Empty or invalid OpenPay ID"**: It happens when you have not properly configured the user ID with the OpenPay.setId () method
204 | * **"Empty or invalid API Key"**: Like the above error happens when you have not configured your API Key with OpenPay.setApiKey () method
205 | * **"Browser error"**: It is triggered when there is an error in the browser that prevents the request to succeed. It may be caused by caracterísiticas that are necessary to run some code and are missing in the browser. For more information see the "Compatibility and Requirements" section.
206 | * **"Request error"**: This error indicates that an error occurred in the server Openpay. May be due to missing parameters, formats, or some other problem that prevents a successful transaction.
207 | * **"Response error (Unknown final status)"**: When this error occurs, it means that the transaction request was submitted successfully to Openpay server but no response was received. This may be due to a problem in Openpay. For more information contact OpenPay.
208 | * **"Timeout after X milliseconds"**: Thrown when the request has taken a long time to run and therefore the response time expires.
209 | * **"Unknown error"**: Raised when there is an unknown error that prevents the request is made. It may be due to problems in the browser or connectivity.
210 |
211 | ## Card Validation Functions
212 | Besides the functions to process card charges, Openpay.js also includes some functions to validate key data necessary to carry out the transaction, especially regarding card numbers.
213 |
214 | Available methods are:
215 |
216 | * `OpenPay.card.validateCardNumber()`
217 | * `OpenPay.card.validateCVC()`
218 | * `OpenPay.card.validateExpiry()`
219 | * `OpenPay.card.cardType()`
220 |
221 | ### Number card validation
222 | To validate a card number can use the method **OpenPay.card.validateCardNumber()**.
223 |
224 | This method receives as parameter a String with the card number to be validated and return one true / false if it is a valid card number and is accepted by Openpay.
225 | Example:
226 | ```javascript
227 | OpenPay.card.validateCardNumber('5555555555554444');
228 | ```
229 | This method is very useful for determining whether a card number is a valid candidate for use with Openpay, so we recommend that you use it before attempting to charge a card.
230 |
231 | Examples:
232 | ```javascript
233 | OpenPay.card.validateCardNumber('5555555555554444'); // TRUE. Valid card number and accepted by OpenPay (MASTERCARD)
234 |
235 | OpenPay.card.validateCardNumber('378282246310005'); // FALSE. Number of valid card but not accepted by OpenPay (AMEX)
236 | ```
237 | ### Security Code Validation
238 | To validate a security code is used the method **OpenPay.card.validateCVC()**.
239 |
240 | This method takes a String as a parameter and returns true / false if the string is valid. Example:
241 | ```javascript
242 | OpenPay.card.validateCVC('123'); // válido
243 | OpenPay.card.validateCVC('1234'); // válido
244 | OpenPay.card.validateCVC('A23'); // inválido
245 | ```
246 | ### Expiration date validation
247 | For this purpose is used the method **OpenPay.card.validateExpiry()**.
248 |
249 | Receive two strings as parameters to represent the month and year of expiry of the card. Returns true / false if the combination of both data, month and year, determine a valid expiration date. Example:
250 | ```javascript
251 | OpenPay.card.validateExpiry('01', '2013'); // inválido
252 | OpenPay.card.validateExpiry('01', '13'); // inválido
253 | OpenPay.card.validateExpiry('05', '2030'); // válido
254 | OpenPay.card.validateExpiry('05', '30'); // válido
255 | ```
256 |
257 | ### Card Type
258 | The type of card that a card number belongs to can be determined most of the time. For this, use the method **OpenPay.card.cardType()**.
259 |
260 | The method receives as a parameter a card number and returns a String with the name of the card type. Examples:
261 | ```javascript
262 | OpenPay.card.cardType('5555555555554444'); // Mastercard
263 | OpenPay.card.cardType('4111111111111111'); // Visa
264 | OpenPay.card.cardType('4917300800000000'); // Visa Electron
265 | OpenPay.card.cardType('378282246310005'); // American Express
266 | OpenPay.card.cardType('30569309025904'); // Diners Club Carte Blanche
267 | OpenPay.card.cardType('6011111111111117'); // Discover
268 | OpenPay.card.cardType('3530111333300000'); // JCB
269 | ```
270 |
271 | ## Fraud detection using device data
272 | OpenPay can use the device information of a transaction in order to better detect fraudulent transactions.
273 | To do this, add the following code to your checkout page, when collecting payment information:
274 | ```HTML
275 |
276 | ```
277 |
278 | Then, in your javascript, call OpenPay.deviceData.setup() to generate a Device Data.
279 |
280 | ```javascript
281 | // If you are testing your application, set Sandbox Mode first
282 | // OpenPay.setSandboxMode(true);
283 | var deviceDataId = OpenPay.deviceData.setup("formId");
284 | ```
285 |
286 | This method generates an identifier for the customer's device data. This value needs to be stored during checkout, and sent to OpenPay when processing the charge.
287 |
288 | The method takes two optional parameters:
289 |
290 | The first is an existing form's id. If given, a new hidden input field will be added to it, with the value of the generated deviceDataId.
291 |
292 | The second parameter specifies the generated field's name and id. If ommited, they will default to "deviceDataId".
293 |
294 | ## Compatibility and requirements
295 | To use Openpay.js You must have one of the following browsers:
296 |
297 | * Chrome 29.0+
298 | * Firefox 23.0+
299 | * Safari 5.1+
300 | * Opera 17.0+
301 | * iOS Safari 4.0+
302 | * Android Browser 2.1+
303 | * Blackberry Browser 7.0+
304 | * IE Mobile 10.0
305 |
306 | Browsers must have support for XMLHttpRequest and JSON Parser libraries.
307 |
--------------------------------------------------------------------------------
/lib/openpay-data.v1.js:
--------------------------------------------------------------------------------
1 | //"use strict";
2 |
3 | (function(){
4 | var _deviceData = function() {};
5 | var _deviceDataSC = function() {};
6 | var _getBeaconKey = function() {};
7 | _deviceData._hostname = "https://api.openpay.mx/";
8 | _deviceData._sandboxHostname = "https://sandbox-api.openpay.mx/";
9 | _deviceData._developHostname = "https://dev-api.openpay.mx/";
10 | _deviceData._deviceDataId = undefined;
11 |
12 | /* Get current deviceDataId or generate new one */
13 | function getDeviceDataId() {
14 | if (_deviceData._deviceDataId === undefined) {
15 | _deviceData._deviceDataId = sjcl.codec.base64.fromBits(sjcl.random.randomWords(6, 0)).replace(/[\+\/]/g,'0');
16 | }
17 | return _deviceData._deviceDataId;
18 | }
19 |
20 |
21 | /* GET ANTI-FRAUD COMPONENTS */
22 | function get_antifraud_comp(hostname, merchant, sessionId){
23 | var antifraudURL = hostname+'antifraud/'+merchant+'/components?s='+sessionId;
24 |
25 | if (window.XDomainRequest) {
26 | var xdr = new XDomainRequest();
27 | xdr.open("GET", antifraudURL);
28 | xdr.onload = function() {
29 | document.body.insertAdjacentHTML("beforeend",xdr.responseText);
30 | }
31 | setTimeout(function () {xdr.send();}, 0);
32 | }else{
33 | var xmlhttp = new XMLHttpRequest();
34 | xmlhttp.onreadystatechange = function(){
35 | if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
36 | document.body.insertAdjacentHTML("beforeend",xmlhttp.responseText);
37 | }
38 | }
39 | xmlhttp.open('GET', antifraudURL , true);
40 | xmlhttp.send();
41 | }
42 |
43 | }
44 |
45 | /* Collect device data */
46 | function collect() {
47 | var hostname;
48 | var sessionId = getDeviceDataId();
49 |
50 | if (OpenPay.developMode) {
51 | hostname = _deviceData._developHostname;
52 | } else if (OpenPay.sandboxMode) {
53 | hostname = _deviceData._sandboxHostname;
54 | } else {
55 | hostname = _deviceData._hostname;
56 | }
57 |
58 | var merchant = OpenPay.getId();
59 | get_antifraud_comp(hostname,merchant,sessionId);
60 |
61 | return getDeviceDataId();
62 | }
63 |
64 | /* Collect device data, and add a hidden field to the form with the given ID if specified. */
65 | _deviceData['setup'] = function(_formId, _hiddenFieldName) {
66 | var sessionId = getDeviceDataId();
67 | if(_formId && document.getElementById(_formId)){
68 | var input = document.createElement("input");
69 | input.setAttribute('type', 'hidden');
70 | input.value = sessionId;
71 | input.name = _hiddenFieldName ? _hiddenFieldName : 'deviceDataId';
72 | input.id = _hiddenFieldName ? _hiddenFieldName : 'deviceDataId';
73 | document.getElementById(_formId).appendChild(input);
74 | }
75 | var isNewLibraryOpenPay = true;
76 |
77 | try {
78 | OpenPay.getId();
79 | OpenPay.getApiKey();
80 | } catch (e) {
81 | isNewLibraryOpenPay = false;
82 | }
83 |
84 | if(isNewLibraryOpenPay){
85 | console.log("executing sift mode");
86 | var publicId = OpenPay.getId();
87 | var apiKey = OpenPay.getApiKey();
88 | var hostname;
89 | if (OpenPay.developMode) {
90 | hostname = _deviceData._developHostname;
91 | } else if (OpenPay.sandboxMode) {
92 | hostname = _deviceData._sandboxHostname;
93 | } else {
94 | hostname = _deviceData._hostname;
95 | }
96 | var url = hostname + "v1/" + publicId +"/antifraudkeys";
97 | //se obtiene el beaconKey de siftscience
98 | try {
99 | OpenPay.getBeaconKey.beaconKey(url, apiKey, "", sessionId,hostname);
100 | } catch(e){
101 | console.log("continue without beaconkey" + e);
102 | }
103 | }
104 |
105 | return collect();
106 | };
107 |
108 | _getBeaconKey['beaconKey'] = function(endpoint, publicKey, userId, sessionId, hostname) {
109 | var _rhr = null, _timer = null, _url = endpoint, _headers = {}, _timeout = 0, _auth = btoa(publicKey + ":");
110 | var _data = {};
111 |
112 | function handleError(_message, _status, _responseText) {
113 | clearTimeout(_timer);
114 | var _data = null;
115 | _message = _message || 'Unknown error';
116 | _status = _status || 0;
117 | _responseText = _responseText || '{}';
118 | try {
119 | _data = JSON.parse(_responseText);
120 | } catch (e) {
121 | _message = 'Response error';
122 | }
123 | };
124 |
125 | if (typeof JSON === 'undefined') {
126 | handleError('Browser error (JSON library not found)');
127 | return;
128 | }
129 |
130 | _timeout = 4e4;
131 | var hasCors = XMLHttpRequest && ("withCredentials" in new XMLHttpRequest());
132 | if(!hasCors){
133 |
134 | if (typeof XDomainRequest !== 'undefined') {
135 | // Inicia jsonp
136 | _data.apiKey = _auth;
137 | var handleResponse = function(data){
138 | if(data.error){
139 | handleError('Request error', data.httpStatus, JSON.stringify(data));
140 | } else {
141 | try {
142 | var beaconKey = data.data;
143 | console.log("beaconKey ok");
144 | if(beaconKey.length > 0){
145 | //Se lanza el script siftScience con el beaconKey obtenido
146 | OpenPay.deviceDataSC.setupSC(userId, sessionId, beaconKey,hostname);
147 | }else{
148 | console.log("Empty beaconKey normal in Sandbox");
149 | }
150 | } catch (e) {
151 | handleError('Response error (Unknown final status)', _rhr.status, '{}');
152 | }
153 | }
154 | };
155 |
156 | var request = {
157 | callbackName:"getResultData",
158 | onSuccess:handleResponse,
159 | onError:handleError,
160 | timeout:_timeout,
161 | url:_url+ "/jsonp",
162 | data:_data
163 | };
164 |
165 | $jsonp.send(request);
166 | // Finaliza jsonp
167 | }else{
168 | handleError('Browser error (CORS not supported)');
169 | return;
170 | }
171 |
172 | } else{
173 |
174 | function getXhr(){
175 | if (isHostMethod(window, "XMLHttpRequest")) {
176 | return new XMLHttpRequest();
177 | }
178 | };
179 |
180 | function isHostMethod(object, property){
181 | var t = typeof object[property];
182 | return t == 'function' ||
183 | (!!(t == 'object' && object[property])) ||
184 | t == 'unknown';
185 | };
186 |
187 | function handleResponseBK(){
188 | // handle only if request has finished
189 | if (typeof _rhr.readyState !== 'undefined' && _rhr.readyState == 4 || !hasCors) {
190 | clearTimeout(_timer);
191 | if (_rhr.status < 200 || _rhr.status >= 300) {
192 | handleError('Request error NO IE', _rhr.status, _rhr.responseText);
193 | } else {
194 | try {
195 | var rt = _rhr.responseText;
196 | rt = rt.replace("(","");
197 | rt = rt.replace(")","");
198 | var jsonResponse = JSON.parse(rt);
199 | var beaconKey = jsonResponse.data;
200 | console.log("beaconKey ok");
201 | if(beaconKey.length > 0){
202 | //Se lanza el script siftScience con el beaconKey obtenido
203 | OpenPay.deviceDataSC.setupSC(userId, sessionId, beaconKey, hostname);
204 | }else{
205 | console.log("Empty beaconKey normal in Sandbox");
206 | }
207 | } catch (e) {
208 | handleError('Response error (Unknown final status) NO IE', _rhr.status, '{}');
209 | }
210 | }
211 | }
212 | };
213 |
214 | if (!(_rhr = getXhr())) {
215 | handleError('Browser error (CORS not supported)');
216 | return;
217 | }
218 |
219 | _headers = {
220 | 'Accept': 'application/json',
221 | 'Content-Type': 'application/json',
222 | 'Authorization': "Basic " + _auth
223 | };
224 |
225 | _rhr.open('GET', _url, true);
226 |
227 | if ('withCredentials' in _rhr) {
228 | _rhr.withCredentials = true;
229 | }
230 |
231 | for (var prop in _headers) {
232 | if (_headers.hasOwnProperty(prop) && _headers[prop]) {
233 | if ('setRequestHeader' in _rhr) {
234 | _rhr.setRequestHeader(prop, _headers[prop]);
235 | }
236 | }
237 | }
238 |
239 | if ('onreadystatechange' in _rhr) {
240 | _rhr.onreadystatechange = handleResponseBK;
241 | } else if ('onload' in _rhr && 'onerror' in _rhr) {
242 | _rhr.onload = handleResponseBK;
243 | _rhr.onerror = handleError;
244 | }
245 |
246 | _timer = setTimeout(function(){
247 |
248 | if ('onload' in _rhr) {
249 | _rhr.onload = Function.prototype;
250 | } else {
251 | _rhr.onreadystatechange = Function.prototype;
252 | }
253 | _rhr.abort();
254 | _rhr = null;
255 | handleError('Timeout after ' + _timeout + ' milliseconds');
256 | }, _timeout);
257 |
258 | _rhr.send();
259 |
260 | }
261 |
262 | }
263 |
264 | /* Initialize the siftscience snippet for device detection */
265 | _deviceDataSC['setupSC'] = function(userId, sessionId, beaconKey, hostname) {
266 | console.log("Sift Snippet");
267 | var _sift = window._sift = window._sift || [];
268 | _sift.push(['_setAccount', beaconKey]);
269 | _sift.push(['_setSessionId', sessionId]);
270 | _sift.push(['_trackPageview']);
271 |
272 | var e = document.createElement('script');
273 | e.type = 'text/javascript';
274 | e.async = true;
275 | e.src = hostname+'antifraud/sc.js';
276 |
277 | var s = document.getElementsByTagName('script')[0];
278 | s.parentNode.insertBefore(e, s);
279 | };
280 |
281 | OpenPay['deviceData'] = _deviceData;
282 |
283 | OpenPay['getBeaconKey'] = _getBeaconKey;
284 |
285 | OpenPay['deviceDataSC'] = _deviceDataSC;
286 |
287 | /* Bundled SJCL library with modules CodecBase64 and Random */
288 |
289 | /*
290 | * Copyright 2009-2010 Emily Stark, Mike Hamburg, Dan Boneh. All rights
291 | * reserved. Redistribution and use in source and binary forms, with or
292 | * without modification, are permitted provided that the following
293 | * conditions are met:
294 | *
295 | * 1. Redistributions of source code must retain the above copyright notice,
296 | * this list of conditions and the following disclaimer.
297 | *
298 | * 2. Redistributions in binary form must reproduce the above copyright
299 | * notice, this list of conditions and the following disclaimer in the
300 | * documentation and/or other materials provided with the distribution.
301 | *
302 | * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
303 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
304 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
305 | * IN NO EVENT SHALL OR CONTRIBUTORS BE LIABLE FOR ANY
306 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
307 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
308 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
309 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
310 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
311 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
312 | * POSSIBILITY OF SUCH DAMAGE.
313 | *
314 | * The views and conclusions contained in the software and documentation are
315 | * those of the authors and should not be interpreted as representing
316 | * official policies, either expressed or implied, of the authors.
317 | */
318 |
319 | var sjcl = {cipher:{}, hash:{}, keyexchange:{}, mode:{}, misc:{}, codec:{}, exception:{corrupt:function(message) {
320 | this.toString = function() {
321 | return"CORRUPT: " + this.message
322 | };
323 | this.message = message
324 | }, invalid:function(message) {
325 | this.toString = function() {
326 | return"INVALID: " + this.message
327 | };
328 | this.message = message
329 | }, bug:function(message) {
330 | this.toString = function() {
331 | return"BUG: " + this.message
332 | };
333 | this.message = message
334 | }, notReady:function(message) {
335 | this.toString = function() {
336 | return"NOT READY: " + this.message
337 | };
338 | this.message = message
339 | }}};
340 | if(typeof module !== "undefined" && module.exports) {
341 | module.exports = sjcl
342 | }
343 | sjcl.cipher.aes = function(key) {
344 | if(!this._tables[0][0][0]) {
345 | this._precompute()
346 | }
347 | var i, j, tmp, encKey, decKey, sbox = this._tables[0][4], decTable = this._tables[1], keyLen = key.length, rcon = 1;
348 | if(keyLen !== 4 && keyLen !== 6 && keyLen !== 8) {
349 | throw new sjcl.exception.invalid("invalid aes key size");
350 | }
351 | this._key = [encKey = key.slice(0), decKey = []];
352 | for(i = keyLen;i < 4 * keyLen + 28;i++) {
353 | tmp = encKey[i - 1];
354 | if(i % keyLen === 0 || keyLen === 8 && i % keyLen === 4) {
355 | tmp = sbox[tmp >>> 24] << 24 ^ sbox[tmp >> 16 & 255] << 16 ^ sbox[tmp >> 8 & 255] << 8 ^ sbox[tmp & 255];
356 | if(i % keyLen === 0) {
357 | tmp = tmp << 8 ^ tmp >>> 24 ^ rcon << 24;
358 | rcon = rcon << 1 ^ (rcon >> 7) * 283
359 | }
360 | }
361 | encKey[i] = encKey[i - keyLen] ^ tmp
362 | }
363 | for(j = 0;i;j++, i--) {
364 | tmp = encKey[j & 3 ? i : i - 4];
365 | if(i <= 4 || j < 4) {
366 | decKey[j] = tmp
367 | }else {
368 | decKey[j] = decTable[0][sbox[tmp >>> 24]] ^ decTable[1][sbox[tmp >> 16 & 255]] ^ decTable[2][sbox[tmp >> 8 & 255]] ^ decTable[3][sbox[tmp & 255]]
369 | }
370 | }
371 | };
372 | sjcl.cipher.aes.prototype = {encrypt:function(data) {
373 | return this._crypt(data, 0)
374 | }, decrypt:function(data) {
375 | return this._crypt(data, 1)
376 | }, _tables:[[[], [], [], [], []], [[], [], [], [], []]], _precompute:function() {
377 | var encTable = this._tables[0], decTable = this._tables[1], sbox = encTable[4], sboxInv = decTable[4], i, x, xInv, d = [], th = [], x2, x4, x8, s, tEnc, tDec;
378 | for(i = 0;i < 0x100;i++) {
379 | th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i
380 | }
381 | for(x = xInv = 0;!sbox[x];x ^= x2 || 1, xInv = th[xInv] || 1) {
382 | s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
383 | s = s >> 8 ^ s & 255 ^ 99;
384 | sbox[x] = s;
385 | sboxInv[s] = x;
386 | x8 = d[x4 = d[x2 = d[x]]];
387 | tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
388 | tEnc = d[s] * 0x101 ^ s * 0x1010100;
389 | for(i = 0;i < 4;i++) {
390 | encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
391 | decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8
392 | }
393 | }
394 | for(i = 0;i < 5;i++) {
395 | encTable[i] = encTable[i].slice(0);
396 | decTable[i] = decTable[i].slice(0)
397 | }
398 | }, _crypt:function(input, dir) {
399 | if(input.length !== 4) {
400 | throw new sjcl.exception.invalid("invalid aes block size");
401 | }
402 | var key = this._key[dir], a = input[0] ^ key[0], b = input[dir ? 3 : 1] ^ key[1], c = input[2] ^ key[2], d = input[dir ? 1 : 3] ^ key[3], a2, b2, c2, nInnerRounds = key.length / 4 - 2, i, kIndex = 4, out = [0, 0, 0, 0], table = this._tables[dir], t0 = table[0], t1 = table[1], t2 = table[2], t3 = table[3], sbox = table[4];
403 | for(i = 0;i < nInnerRounds;i++) {
404 | a2 = t0[a >>> 24] ^ t1[b >> 16 & 255] ^ t2[c >> 8 & 255] ^ t3[d & 255] ^ key[kIndex];
405 | b2 = t0[b >>> 24] ^ t1[c >> 16 & 255] ^ t2[d >> 8 & 255] ^ t3[a & 255] ^ key[kIndex + 1];
406 | c2 = t0[c >>> 24] ^ t1[d >> 16 & 255] ^ t2[a >> 8 & 255] ^ t3[b & 255] ^ key[kIndex + 2];
407 | d = t0[d >>> 24] ^ t1[a >> 16 & 255] ^ t2[b >> 8 & 255] ^ t3[c & 255] ^ key[kIndex + 3];
408 | kIndex += 4;
409 | a = a2;
410 | b = b2;
411 | c = c2
412 | }
413 | for(i = 0;i < 4;i++) {
414 | out[dir ? 3 & -i : i] = sbox[a >>> 24] << 24 ^ sbox[b >> 16 & 255] << 16 ^ sbox[c >> 8 & 255] << 8 ^ sbox[d & 255] ^ key[kIndex++];
415 | a2 = a;
416 | a = b;
417 | b = c;
418 | c = d;
419 | d = a2
420 | }
421 | return out
422 | }};
423 | sjcl.bitArray = {bitSlice:function(a, bstart, bend) {
424 | a = sjcl.bitArray._shiftRight(a.slice(bstart / 32), 32 - (bstart & 31)).slice(1);
425 | return bend === undefined ? a : sjcl.bitArray.clamp(a, bend - bstart)
426 | }, extract:function(a, bstart, blength) {
427 | var x, sh = Math.floor(-bstart - blength & 31);
428 | if((bstart + blength - 1 ^ bstart) & -32) {
429 | x = a[bstart / 32 | 0] << 32 - sh ^ a[bstart / 32 + 1 | 0] >>> sh
430 | }else {
431 | x = a[bstart / 32 | 0] >>> sh
432 | }
433 | return x & (1 << blength) - 1
434 | }, concat:function(a1, a2) {
435 | if(a1.length === 0 || a2.length === 0) {
436 | return a1.concat(a2)
437 | }
438 | var out, i, last = a1[a1.length - 1], shift = sjcl.bitArray.getPartial(last);
439 | if(shift === 32) {
440 | return a1.concat(a2)
441 | }else {
442 | return sjcl.bitArray._shiftRight(a2, shift, last | 0, a1.slice(0, a1.length - 1))
443 | }
444 | }, bitLength:function(a) {
445 | var l = a.length, x;
446 | if(l === 0) {
447 | return 0
448 | }
449 | x = a[l - 1];
450 | return(l - 1) * 32 + sjcl.bitArray.getPartial(x)
451 | }, clamp:function(a, len) {
452 | if(a.length * 32 < len) {
453 | return a
454 | }
455 | a = a.slice(0, Math.ceil(len / 32));
456 | var l = a.length;
457 | len = len & 31;
458 | if(l > 0 && len) {
459 | a[l - 1] = sjcl.bitArray.partial(len, a[l - 1] & 2147483648 >> len - 1, 1)
460 | }
461 | return a
462 | }, partial:function(len, x, _end) {
463 | if(len === 32) {
464 | return x
465 | }
466 | return(_end ? x | 0 : x << 32 - len) + len * 0x10000000000
467 | }, getPartial:function(x) {
468 | return Math.round(x / 0x10000000000) || 32
469 | }, equal:function(a, b) {
470 | if(sjcl.bitArray.bitLength(a) !== sjcl.bitArray.bitLength(b)) {
471 | return false
472 | }
473 | var x = 0, i;
474 | for(i = 0;i < a.length;i++) {
475 | x |= a[i] ^ b[i]
476 | }
477 | return x === 0
478 | }, _shiftRight:function(a, shift, carry, out) {
479 | var i, last2 = 0, shift2;
480 | if(out === undefined) {
481 | out = []
482 | }
483 | for(;shift >= 32;shift -= 32) {
484 | out.push(carry);
485 | carry = 0
486 | }
487 | if(shift === 0) {
488 | return out.concat(a)
489 | }
490 | for(i = 0;i < a.length;i++) {
491 | out.push(carry | a[i] >>> shift);
492 | carry = a[i] << 32 - shift
493 | }
494 | last2 = a.length ? a[a.length - 1] : 0;
495 | shift2 = sjcl.bitArray.getPartial(last2);
496 | out.push(sjcl.bitArray.partial(shift + shift2 & 31, shift + shift2 > 32 ? carry : out.pop(), 1));
497 | return out
498 | }, _xor4:function(x, y) {
499 | return[x[0] ^ y[0], x[1] ^ y[1], x[2] ^ y[2], x[3] ^ y[3]]
500 | }};
501 | sjcl.codec.utf8String = {fromBits:function(arr) {
502 | var out = "", bl = sjcl.bitArray.bitLength(arr), i, tmp;
503 | for(i = 0;i < bl / 8;i++) {
504 | if((i & 3) === 0) {
505 | tmp = arr[i / 4]
506 | }
507 | out += String.fromCharCode(tmp >>> 24);
508 | tmp <<= 8
509 | }
510 | return decodeURIComponent(escape(out))
511 | }, toBits:function(str) {
512 | str = unescape(encodeURIComponent(str));
513 | var out = [], i, tmp = 0;
514 | for(i = 0;i < str.length;i++) {
515 | tmp = tmp << 8 | str.charCodeAt(i);
516 | if((i & 3) === 3) {
517 | out.push(tmp);
518 | tmp = 0
519 | }
520 | }
521 | if(i & 3) {
522 | out.push(sjcl.bitArray.partial(8 * (i & 3), tmp))
523 | }
524 | return out
525 | }};
526 | sjcl.codec.base64 = {_chars:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", fromBits:function(arr, _noEquals, _url) {
527 | var out = "", i, bits = 0, c = sjcl.codec.base64._chars, ta = 0, bl = sjcl.bitArray.bitLength(arr);
528 | if(_url) {
529 | c = c.substr(0, 62) + "-_"
530 | }
531 | for(i = 0;out.length * 6 < bl;) {
532 | out += c.charAt((ta ^ arr[i] >>> bits) >>> 26);
533 | if(bits < 6) {
534 | ta = arr[i] << 6 - bits;
535 | bits += 26;
536 | i++
537 | }else {
538 | ta <<= 6;
539 | bits -= 6
540 | }
541 | }
542 | while(out.length & 3 && !_noEquals) {
543 | out += "="
544 | }
545 | return out
546 | }, toBits:function(str, _url) {
547 | str = str.replace(/\s|=/g, "");
548 | var out = [], i, bits = 0, c = sjcl.codec.base64._chars, ta = 0, x;
549 | if(_url) {
550 | c = c.substr(0, 62) + "-_"
551 | }
552 | for(i = 0;i < str.length;i++) {
553 | x = c.indexOf(str.charAt(i));
554 | if(x < 0) {
555 | throw new sjcl.exception.invalid("this isn't base64!");
556 | }
557 | if(bits > 26) {
558 | bits -= 26;
559 | out.push(ta ^ x >>> bits);
560 | ta = x << 32 - bits
561 | }else {
562 | bits += 6;
563 | ta ^= x << 32 - bits
564 | }
565 | }
566 | if(bits & 56) {
567 | out.push(sjcl.bitArray.partial(bits & 56, ta, 1))
568 | }
569 | return out
570 | }};
571 | sjcl.codec.base64url = {fromBits:function(arr) {
572 | return sjcl.codec.base64.fromBits(arr, 1, 1)
573 | }, toBits:function(str) {
574 | return sjcl.codec.base64.toBits(str, 1)
575 | }};
576 | sjcl.hash.sha256 = function(hash) {
577 | if(!this._key[0]) {
578 | this._precompute()
579 | }
580 | if(hash) {
581 | this._h = hash._h.slice(0);
582 | this._buffer = hash._buffer.slice(0);
583 | this._length = hash._length
584 | }else {
585 | this.reset()
586 | }
587 | };
588 | sjcl.hash.sha256.hash = function(data) {
589 | return(new sjcl.hash.sha256).update(data).finalize()
590 | };
591 | sjcl.hash.sha256.prototype = {blockSize:512, reset:function() {
592 | this._h = this._init.slice(0);
593 | this._buffer = [];
594 | this._length = 0;
595 | return this
596 | }, update:function(data) {
597 | if(typeof data === "string") {
598 | data = sjcl.codec.utf8String.toBits(data)
599 | }
600 | var i, b = this._buffer = sjcl.bitArray.concat(this._buffer, data), ol = this._length, nl = this._length = ol + sjcl.bitArray.bitLength(data);
601 | for(i = 512 + ol & -512;i <= nl;i += 512) {
602 | this._block(b.splice(0, 16))
603 | }
604 | return this
605 | }, finalize:function() {
606 | var i, b = this._buffer, h = this._h;
607 | b = sjcl.bitArray.concat(b, [sjcl.bitArray.partial(1, 1)]);
608 | for(i = b.length + 2;i & 15;i++) {
609 | b.push(0)
610 | }
611 | b.push(Math.floor(this._length / 0x100000000));
612 | b.push(this._length | 0);
613 | while(b.length) {
614 | this._block(b.splice(0, 16))
615 | }
616 | this.reset();
617 | return h
618 | }, _init:[], _key:[], _precompute:function() {
619 | var i = 0, prime = 2, factor;
620 | function frac(x) {
621 | return(x - Math.floor(x)) * 0x100000000 | 0
622 | }
623 | outer:for(;i < 64;prime++) {
624 | for(factor = 2;factor * factor <= prime;factor++) {
625 | if(prime % factor === 0) {
626 | continue outer
627 | }
628 | }
629 | if(i < 8) {
630 | this._init[i] = frac(Math.pow(prime, 1 / 2))
631 | }
632 | this._key[i] = frac(Math.pow(prime, 1 / 3));
633 | i++
634 | }
635 | }, _block:function(words) {
636 | var i, tmp, a, b, w = words.slice(0), h = this._h, k = this._key, h0 = h[0], h1 = h[1], h2 = h[2], h3 = h[3], h4 = h[4], h5 = h[5], h6 = h[6], h7 = h[7];
637 | for(i = 0;i < 64;i++) {
638 | if(i < 16) {
639 | tmp = w[i]
640 | }else {
641 | a = w[i + 1 & 15];
642 | b = w[i + 14 & 15];
643 | tmp = w[i & 15] = (a >>> 7 ^ a >>> 18 ^ a >>> 3 ^ a << 25 ^ a << 14) + (b >>> 17 ^ b >>> 19 ^ b >>> 10 ^ b << 15 ^ b << 13) + w[i & 15] + w[i + 9 & 15] | 0
644 | }
645 | tmp = tmp + h7 + (h4 >>> 6 ^ h4 >>> 11 ^ h4 >>> 25 ^ h4 << 26 ^ h4 << 21 ^ h4 << 7) + (h6 ^ h4 & (h5 ^ h6)) + k[i];
646 | h7 = h6;
647 | h6 = h5;
648 | h5 = h4;
649 | h4 = h3 + tmp | 0;
650 | h3 = h2;
651 | h2 = h1;
652 | h1 = h0;
653 | h0 = tmp + (h1 & h2 ^ h3 & (h1 ^ h2)) + (h1 >>> 2 ^ h1 >>> 13 ^ h1 >>> 22 ^ h1 << 30 ^ h1 << 19 ^ h1 << 10) | 0
654 | }
655 | h[0] = h[0] + h0 | 0;
656 | h[1] = h[1] + h1 | 0;
657 | h[2] = h[2] + h2 | 0;
658 | h[3] = h[3] + h3 | 0;
659 | h[4] = h[4] + h4 | 0;
660 | h[5] = h[5] + h5 | 0;
661 | h[6] = h[6] + h6 | 0;
662 | h[7] = h[7] + h7 | 0
663 | }};
664 | sjcl.prng = function(defaultParanoia) {
665 | this._pools = [new sjcl.hash.sha256];
666 | this._poolEntropy = [0];
667 | this._reseedCount = 0;
668 | this._robins = {};
669 | this._eventId = 0;
670 | this._collectorIds = {};
671 | this._collectorIdNext = 0;
672 | this._strength = 0;
673 | this._poolStrength = 0;
674 | this._nextReseed = 0;
675 | this._key = [0, 0, 0, 0, 0, 0, 0, 0];
676 | this._counter = [0, 0, 0, 0];
677 | this._cipher = undefined;
678 | this._defaultParanoia = defaultParanoia;
679 | this._collectorsStarted = false;
680 | this._callbacks = {progress:{}, seeded:{}};
681 | this._callbackI = 0;
682 | this._NOT_READY = 0;
683 | this._READY = 1;
684 | this._REQUIRES_RESEED = 2;
685 | this._MAX_WORDS_PER_BURST = 0x10000;
686 | this._PARANOIA_LEVELS = [0, 48, 64, 96, 128, 192, 0x100, 384, 512, 768, 1024];
687 | this._MILLISECONDS_PER_RESEED = 3E4;
688 | this._BITS_PER_RESEED = 80
689 | };
690 | sjcl.prng.prototype = {randomWords:function(nwords, paranoia) {
691 | var out = [], i, readiness = this.isReady(paranoia), g;
692 | if(readiness === this._NOT_READY) {
693 | throw new sjcl.exception.notReady("generator isn't seeded");
694 | }else {
695 | if(readiness & this._REQUIRES_RESEED) {
696 | this._reseedFromPools(!(readiness & this._READY))
697 | }
698 | }
699 | for(i = 0;i < nwords;i += 4) {
700 | if((i + 1) % this._MAX_WORDS_PER_BURST === 0) {
701 | this._gate()
702 | }
703 | g = this._gen4words();
704 | out.push(g[0], g[1], g[2], g[3])
705 | }
706 | this._gate();
707 | return out.slice(0, nwords)
708 | }, setDefaultParanoia:function(paranoia, allowZeroParanoia) {
709 | if(paranoia === 0 && allowZeroParanoia !== "Setting paranoia=0 will ruin your security; use it only for testing") {
710 | throw"Setting paranoia=0 will ruin your security; use it only for testing";
711 | }
712 | this._defaultParanoia = paranoia
713 | }, addEntropy:function(data, estimatedEntropy, source) {
714 | source = source || "user";
715 | var id, i, tmp, t = (new Date).valueOf(), robin = this._robins[source], oldReady = this.isReady(), err = 0, objName;
716 | id = this._collectorIds[source];
717 | if(id === undefined) {
718 | id = this._collectorIds[source] = this._collectorIdNext++
719 | }
720 | if(robin === undefined) {
721 | robin = this._robins[source] = 0
722 | }
723 | this._robins[source] = (this._robins[source] + 1) % this._pools.length;
724 | switch(typeof data) {
725 | case "number":
726 | if(estimatedEntropy === undefined) {
727 | estimatedEntropy = 1
728 | }
729 | this._pools[robin].update([id, this._eventId++, 1, estimatedEntropy, t, 1, data | 0]);
730 | break;
731 | case "object":
732 | objName = Object.prototype.toString.call(data);
733 | if(objName === "[object Uint32Array]") {
734 | tmp = [];
735 | for(i = 0;i < data.length;i++) {
736 | tmp.push(data[i])
737 | }
738 | data = tmp
739 | }else {
740 | if(objName !== "[object Array]") {
741 | err = 1
742 | }
743 | for(i = 0;i < data.length && !err;i++) {
744 | if(typeof data[i] !== "number") {
745 | err = 1
746 | }
747 | }
748 | }
749 | if(!err) {
750 | if(estimatedEntropy === undefined) {
751 | estimatedEntropy = 0;
752 | for(i = 0;i < data.length;i++) {
753 | tmp = data[i];
754 | while(tmp > 0) {
755 | estimatedEntropy++;
756 | tmp = tmp >>> 1
757 | }
758 | }
759 | }
760 | this._pools[robin].update([id, this._eventId++, 2, estimatedEntropy, t, data.length].concat(data))
761 | }
762 | break;
763 | case "string":
764 | if(estimatedEntropy === undefined) {
765 | estimatedEntropy = data.length
766 | }
767 | this._pools[robin].update([id, this._eventId++, 3, estimatedEntropy, t, data.length]);
768 | this._pools[robin].update(data);
769 | break;
770 | default:
771 | err = 1
772 | }
773 | if(err) {
774 | throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");
775 | }
776 | this._poolEntropy[robin] += estimatedEntropy;
777 | this._poolStrength += estimatedEntropy;
778 | if(oldReady === this._NOT_READY) {
779 | if(this.isReady() !== this._NOT_READY) {
780 | this._fireEvent("seeded", Math.max(this._strength, this._poolStrength))
781 | }
782 | this._fireEvent("progress", this.getProgress())
783 | }
784 | }, isReady:function(paranoia) {
785 | var entropyRequired = this._PARANOIA_LEVELS[paranoia !== undefined ? paranoia : this._defaultParanoia];
786 | if(this._strength && this._strength >= entropyRequired) {
787 | return this._poolEntropy[0] > this._BITS_PER_RESEED && (new Date).valueOf() > this._nextReseed ? this._REQUIRES_RESEED | this._READY : this._READY
788 | }else {
789 | return this._poolStrength >= entropyRequired ? this._REQUIRES_RESEED | this._NOT_READY : this._NOT_READY
790 | }
791 | }, getProgress:function(paranoia) {
792 | var entropyRequired = this._PARANOIA_LEVELS[paranoia ? paranoia : this._defaultParanoia];
793 | if(this._strength >= entropyRequired) {
794 | return 1
795 | }else {
796 | return this._poolStrength > entropyRequired ? 1 : this._poolStrength / entropyRequired
797 | }
798 | }, startCollectors:function() {
799 | if(this._collectorsStarted) {
800 | return
801 | }
802 | this._eventListener = {loadTimeCollector:this._bind(this._loadTimeCollector), mouseCollector:this._bind(this._mouseCollector), accelerometerCollector:this._bind(this._accelerometerCollector)};
803 | if(window.addEventListener) {
804 | window.addEventListener("load", this._eventListener.loadTimeCollector, false);
805 | window.addEventListener("mousemove", this._eventListener.mouseCollector, false);
806 | window.addEventListener("devicemotion", this._eventListener.accelerometerCollector, false)
807 | }else {
808 | if(document.attachEvent) {
809 | document.attachEvent("onload", this._eventListener.loadTimeCollector);
810 | document.attachEvent("onmousemove", this._eventListener.mouseCollector);
811 | }else {
812 | throw new sjcl.exception.bug("can't attach event");
813 | }
814 | }
815 | this._collectorsStarted = true
816 | }, stopCollectors:function() {
817 | if(!this._collectorsStarted) {
818 | return
819 | }
820 | if(window.removeEventListener) {
821 | window.removeEventListener("load", this._eventListener.loadTimeCollector, false);
822 | window.removeEventListener("mousemove", this._eventListener.mouseCollector, false);
823 | window.removeEventListener("devicemotion", this._eventListener.accelerometerCollector, false)
824 | }else {
825 | if(document.detachEvent) {
826 | document.detachEvent("onload", this._eventListener.loadTimeCollector);
827 | document.detachEvent("onmousemove", this._eventListener.mouseCollector);
828 | }
829 | }
830 | this._collectorsStarted = false
831 | }, addEventListener:function(name, callback) {
832 | this._callbacks[name][this._callbackI++] = callback
833 | }, removeEventListener:function(name, cb) {
834 | var i, j, cbs = this._callbacks[name], jsTemp = [];
835 | for(j in cbs) {
836 | if(cbs.hasOwnProperty(j) && cbs[j] === cb) {
837 | jsTemp.push(j)
838 | }
839 | }
840 | for(i = 0;i < jsTemp.length;i++) {
841 | j = jsTemp[i];
842 | delete cbs[j]
843 | }
844 | }, _bind:function(func) {
845 | var that = this;
846 | return function() {
847 | func.apply(that, arguments)
848 | }
849 | }, _gen4words:function() {
850 | for(var i = 0;i < 4;i++) {
851 | this._counter[i] = this._counter[i] + 1 | 0;
852 | if(this._counter[i]) {
853 | break
854 | }
855 | }
856 | return this._cipher.encrypt(this._counter)
857 | }, _gate:function() {
858 | this._key = this._gen4words().concat(this._gen4words());
859 | this._cipher = new sjcl.cipher.aes(this._key)
860 | }, _reseed:function(seedWords) {
861 | this._key = sjcl.hash.sha256.hash(this._key.concat(seedWords));
862 | this._cipher = new sjcl.cipher.aes(this._key);
863 | for(var i = 0;i < 4;i++) {
864 | this._counter[i] = this._counter[i] + 1 | 0;
865 | if(this._counter[i]) {
866 | break
867 | }
868 | }
869 | }, _reseedFromPools:function(full) {
870 | var reseedData = [], strength = 0, i;
871 | this._nextReseed = reseedData[0] = (new Date).valueOf() + this._MILLISECONDS_PER_RESEED;
872 | for(i = 0;i < 16;i++) {
873 | reseedData.push(Math.random() * 0x100000000 | 0)
874 | }
875 | for(i = 0;i < this._pools.length;i++) {
876 | reseedData = reseedData.concat(this._pools[i].finalize());
877 | strength += this._poolEntropy[i];
878 | this._poolEntropy[i] = 0;
879 | if(!full && this._reseedCount & 1 << i) {
880 | break
881 | }
882 | }
883 | if(this._reseedCount >= 1 << this._pools.length) {
884 | this._pools.push(new sjcl.hash.sha256);
885 | this._poolEntropy.push(0)
886 | }
887 | this._poolStrength -= strength;
888 | if(strength > this._strength) {
889 | this._strength = strength
890 | }
891 | this._reseedCount++;
892 | this._reseed(reseedData)
893 | }, _mouseCollector:function(ev) {
894 | var x = ev.x || ev.clientX || ev.offsetX || 0, y = ev.y || ev.clientY || ev.offsetY || 0;
895 | sjcl.random.addEntropy([x, y], 2, "mouse");
896 | this._addCurrentTimeToEntropy(0)
897 | }, _loadTimeCollector:function() {
898 | this._addCurrentTimeToEntropy(2)
899 | }, _addCurrentTimeToEntropy:function(estimatedEntropy) {
900 | if(window && window.performance && typeof window.performance.now === "function") {
901 | sjcl.random.addEntropy(window.performance.now(), estimatedEntropy, "loadtime")
902 | }else {
903 | sjcl.random.addEntropy((new Date).valueOf(), estimatedEntropy, "loadtime")
904 | }
905 | }, _accelerometerCollector:function(ev) {
906 | var ac = ev.accelerationIncludingGravity.x || ev.accelerationIncludingGravity.y || ev.accelerationIncludingGravity.z;
907 | if(window.orientation) {
908 | var or = window.orientation;
909 | if(typeof or === "number") {
910 | sjcl.random.addEntropy(or, 1, "accelerometer")
911 | }
912 | }
913 | if(ac) {
914 | sjcl.random.addEntropy(ac, 2, "accelerometer")
915 | }
916 | this._addCurrentTimeToEntropy(0)
917 | }, _fireEvent:function(name, arg) {
918 | var j, cbs = sjcl.random._callbacks[name], cbsTemp = [];
919 | for(j in cbs) {
920 | if(cbs.hasOwnProperty(j)) {
921 | cbsTemp.push(cbs[j])
922 | }
923 | }
924 | for(j = 0;j < cbsTemp.length;j++) {
925 | cbsTemp[j](arg)
926 | }
927 | }};
928 | sjcl.random = new sjcl.prng(6);
929 | (function() {
930 | try {
931 | var buf, crypt, getRandomValues, ab;
932 | if(typeof module !== "undefined" && module.exports && (crypt = require("crypto")) && crypt.randomBytes) {
933 | buf = crypt.randomBytes(1024 / 8);
934 | buf = new Uint32Array((new Uint8Array(buf)).buffer);
935 | sjcl.random.addEntropy(buf, 1024, "crypto.randomBytes")
936 | }else {
937 | if(window && Uint32Array) {
938 | ab = new Uint32Array(32);
939 | if(window.crypto && window.crypto.getRandomValues) {
940 | window.crypto.getRandomValues(ab)
941 | }else {
942 | if(window.msCrypto && window.msCrypto.getRandomValues) {
943 | window.msCrypto.getRandomValues(ab)
944 | }else {
945 | return
946 | }
947 | }
948 | sjcl.random.addEntropy(ab, 1024, "crypto.getRandomValues")
949 | }else {
950 | }
951 | }
952 | }catch(e) {
953 | console.log("There was an error collecting entropy from the browser:");
954 | console.log(e)
955 | }
956 | })();
957 | }).call(this);
958 |
959 |
--------------------------------------------------------------------------------
/lib/openpay-data.v1.min.js:
--------------------------------------------------------------------------------
1 | /*! openpay-data.js v1.2.39 2023-07-25 */
2 | !function(){var r=function(){},t=function(){},e=function(){};function s(){return r._deviceDataId=r._deviceDataId===undefined?v.codec.base64.fromBits(v.random.randomWords(6,0)).replace(/[\+\/]/g,"0"):r._deviceDataId}function a(){var t,e,n=s(),o=OpenPay.developMode?r._developHostname:OpenPay.sandboxMode?r._sandboxHostname:r._hostname,i=OpenPay.getId();return o=(o=o)+"antifraud/"+i+"/components?s="+n,window.XDomainRequest?((t=new XDomainRequest).open("GET",o),t.onload=function(){document.body.insertAdjacentHTML("beforeend",t.responseText)},setTimeout(function(){t.send()},0)):((e=new XMLHttpRequest).onreadystatechange=function(){4==e.readyState&&200==e.status&&document.body.insertAdjacentHTML("beforeend",e.responseText)},e.open("GET",o,!0),e.send()),s()}r._hostname="https://api.openpay.mx/",r._sandboxHostname="https://sandbox-api.openpay.mx/",r._developHostname="https://dev-api.openpay.mx/",r._deviceDataId=undefined,r.setup=function(t,e){var n=s(),e=(t&&document.getElementById(t)&&((o=document.createElement("input")).setAttribute("type","hidden"),o.value=n,o.name=e||"deviceDataId",o.id=e||"deviceDataId",document.getElementById(t).appendChild(o)),!0);try{OpenPay.getId(),OpenPay.getApiKey()}catch(i){e=!1}if(e){console.log("executing sift mode");var t=OpenPay.getId(),o=OpenPay.getApiKey(),e=OpenPay.developMode?r._developHostname:OpenPay.sandboxMode?r._sandboxHostname:r._hostname,t=e+"v1/"+t+"/antifraudkeys";try{OpenPay.getBeaconKey.beaconKey(t,o,"",n,e)}catch(i){console.log("continue without beaconkey"+i)}}return a()},e.beaconKey=function(t,e,o,i,r){var s=null,a=null,n={},e=btoa(e+":"),c={};function h(t,e,n){clearTimeout(a);n=n||"{}";try{JSON.parse(n)}catch(o){}}if("undefined"==typeof JSON)h();else{var l=XMLHttpRequest&&"withCredentials"in new XMLHttpRequest;if(l){function d(){if("undefined"!=typeof s.readyState&&4==s.readyState||!l)if(clearTimeout(a),s.status<200||300<=s.status)h(0,s.status,s.responseText);else try{var t=s.responseText;t=(t=t.replace("(","")).replace(")","");var e=JSON.parse(t).data;console.log("beaconKey ok"),0>>24]<<24^s[o>>16&255]<<16^s[o>>8&255]<<8^s[255&o],e%c==0)&&(o=o<<8^o>>>24^h<<24,h=h<<1^283*(h>>7)),i[e]=i[e-c]^o;for(n=0;e;n++,e--)o=i[3&n?e:e-4],r[n]=e<=4||n<4?o:a[0][s[o>>>24]]^a[1][s[o>>16&255]]^a[2][s[o>>8&255]]^a[3][s[255&o]]},v.cipher.aes.prototype={encrypt:function(t){return this._crypt(t,0)},decrypt:function(t){return this._crypt(t,1)},_tables:[[[],[],[],[],[]],[[],[],[],[],[]]],_precompute:function(){for(var t,e,n,o,i,r,s,a=this._tables[0],c=this._tables[1],h=a[4],l=c[4],d=[],u=[],p=0;p<256;p++)u[(d[p]=p<<1^283*(p>>7))^p]=p;for(t=e=0;!h[t];t^=n||1,e=u[e]||1)for(s=16843009*d[o=d[n=d[l[h[t]=i=(i=e^e<<1^e<<2^e<<3^e<<4)>>8^255&i^99]=t]]]^65537*o^257*n^16843008*t,r=257*d[i]^16843008*i,p=0;p<4;p++)a[p][t]=r=r<<24^r>>>8,c[p][i]=s=s<<24^s>>>8;for(p=0;p<5;p++)a[p]=a[p].slice(0),c[p]=c[p].slice(0)},_crypt:function(t,e){if(4!==t.length)throw new v.exception.invalid("invalid aes block size");for(var n,o,i,r=this._key[e],s=t[0]^r[0],a=t[e?3:1]^r[1],c=t[2]^r[2],h=t[e?1:3]^r[3],l=r.length/4-2,d=4,u=[0,0,0,0],t=this._tables[e],p=t[0],_=t[1],f=t[2],y=t[3],m=t[4],g=0;g>>24]^_[a>>16&255]^f[c>>8&255]^y[255&h]^r[d],o=p[a>>>24]^_[c>>16&255]^f[h>>8&255]^y[255&s]^r[d+1],i=p[c>>>24]^_[h>>16&255]^f[s>>8&255]^y[255&a]^r[d+2],h=p[h>>>24]^_[s>>16&255]^f[a>>8&255]^y[255&c]^r[d+3],d+=4,s=n,a=o,c=i;for(g=0;g<4;g++)u[e?3&-g:g]=m[s>>>24]<<24^m[a>>16&255]<<16^m[c>>8&255]<<8^m[255&h]^r[d++],n=s,s=a,a=c,c=h,h=n;return u}},v.bitArray={bitSlice:function(t,e,n){return t=v.bitArray._shiftRight(t.slice(e/32),32-(31&e)).slice(1),n===undefined?t:v.bitArray.clamp(t,n-e)},extract:function(t,e,n){var o=Math.floor(-e-n&31),e=-32&(e+n-1^e)?t[e/32|0]<<32-o^t[e/32+1|0]>>>o:t[e/32|0]>>>o;return e&(1<>e-1,1))),t},partial:function(t,e,n){return 32===t?e:(n?0|e:e<<32-t)+1099511627776*t},getPartial:function(t){return Math.round(t/1099511627776)||32},equal:function(t,e){if(v.bitArray.bitLength(t)!==v.bitArray.bitLength(e))return!1;for(var n=0,o=0;o>>e),n=t[i]<<32-e;return r=t.length?t[t.length-1]:0,r=v.bitArray.getPartial(r),o.push(v.bitArray.partial(e+r&31,32>>24),e<<=8;return decodeURIComponent(escape(n))},toBits:function(t){t=unescape(encodeURIComponent(t));for(var e=[],n=0,o=0;o>>r)>>>26),r<6?(a=t[o]<<6-r,r+=26,o++):(a<<=6,r-=6);for(;3&i.length&&!e;)i+="=";return i},toBits:function(t,e){t=t.replace(/\s|=/g,"");var n,o,i=[],r=0,s=v.codec.base64._chars,a=0;for(e&&(s=s.substr(0,62)+"-_"),n=0;n>>(r-=26)),a=o<<32-r):a^=o<<32-(r+=6)}return 56&r&&i.push(v.bitArray.partial(56&r,a,1)),i}},v.codec.base64url={fromBits:function(t){return v.codec.base64.fromBits(t,1,1)},toBits:function(t){return v.codec.base64.toBits(t,1)}},v.hash.sha256=function(t){this._key[0]||this._precompute(),t?(this._h=t._h.slice(0),this._buffer=t._buffer.slice(0),this._length=t._length):this.reset()},v.hash.sha256.hash=function(t){return(new v.hash.sha256).update(t).finalize()},v.hash.sha256.prototype={blockSize:512,reset:function(){return this._h=this._init.slice(0),this._buffer=[],this._length=0,this},update:function(t){"string"==typeof t&&(t=v.codec.utf8String.toBits(t));for(var e=this._buffer=v.bitArray.concat(this._buffer,t),n=this._length,o=this._length=n+v.bitArray.bitLength(t),i=512+n&-512;i<=o;i+=512)this._block(e.splice(0,16));return this},finalize:function(){for(var t=this._buffer,e=this._h,n=(t=v.bitArray.concat(t,[v.bitArray.partial(1,1)])).length+2;15&n;n++)t.push(0);for(t.push(Math.floor(this._length/4294967296)),t.push(0|this._length);t.length;)this._block(t.splice(0,16));return this.reset(),e},_init:[],_key:[],_precompute:function(){var t,e=0,n=2;function o(t){return 4294967296*(t-Math.floor(t))|0}t:for(;e<64;n++){for(t=2;t*t<=n;t++)if(n%t==0)continue t;e<8&&(this._init[e]=o(Math.pow(n,.5))),this._key[e]=o(Math.pow(n,1/3)),e++}},_block:function(t){for(var e,n,o=t.slice(0),t=this._h,i=this._key,r=t[0],s=t[1],a=t[2],c=t[3],h=t[4],l=t[5],d=t[6],u=t[7],p=0;p<64;p++)e=(e=p<16?o[p]:(e=o[p+1&15],n=o[p+14&15],o[15&p]=(e>>>7^e>>>18^e>>>3^e<<25^e<<14)+(n>>>17^n>>>19^n>>>10^n<<15^n<<13)+o[15&p]+o[p+9&15]|0))+u+(h>>>6^h>>>11^h>>>25^h<<26^h<<21^h<<7)+(d^h&(l^d))+i[p],u=d,d=l,l=h,h=c+e|0,c=a,a=s,r=e+((s=r)&a^c&(s^a))+(s>>>2^s>>>13^s>>>22^s<<30^s<<19^s<<10)|0;t[0]=t[0]+r|0,t[1]=t[1]+s|0,t[2]=t[2]+a|0,t[3]=t[3]+c|0,t[4]=t[4]+h|0,t[5]=t[5]+l|0,t[6]=t[6]+d|0,t[7]=t[7]+u|0}},v.prng=function(t){this._pools=[new v.hash.sha256],this._poolEntropy=[0],this._reseedCount=0,this._robins={},this._eventId=0,this._collectorIds={},this._collectorIdNext=0,this._strength=0,this._poolStrength=0,this._nextReseed=0,this._key=[0,0,0,0,0,0,0,0],this._counter=[0,0,0,0],this._cipher=undefined,this._defaultParanoia=t,this._collectorsStarted=!1,this._callbacks={progress:{},seeded:{}},this._callbackI=0,this._NOT_READY=0,this._READY=1,this._REQUIRES_RESEED=2,this._MAX_WORDS_PER_BURST=65536,this._PARANOIA_LEVELS=[0,48,64,96,128,192,256,384,512,768,1024],this._MILLISECONDS_PER_RESEED=3e4,this._BITS_PER_RESEED=80},v.prng.prototype={randomWords:function(t,e){var n,o,i=[],e=this.isReady(e);if(e===this._NOT_READY)throw new v.exception.notReady("generator isn't seeded");for(e&this._REQUIRES_RESEED&&this._reseedFromPools(!(e&this._READY)),n=0;n>>=1;this._pools[a].update([l,this._eventId++,2,e,s,t.length].concat(t))}break;case"string":e===undefined&&(e=t.length),this._pools[a].update([l,this._eventId++,3,e,s,t.length]),this._pools[a].update(t);break;default:h=1}if(h)throw new v.exception.bug("random: addEntropy only supports number, array of numbers or string");this._poolEntropy[a]+=e,this._poolStrength+=e,c===this._NOT_READY&&(this.isReady()!==this._NOT_READY&&this._fireEvent("seeded",Math.max(this._strength,this._poolStrength)),this._fireEvent("progress",this.getProgress()))},isReady:function(t){t=this._PARANOIA_LEVELS[t!==undefined?t:this._defaultParanoia];return this._strength&&this._strength>=t?this._poolEntropy[0]>this._BITS_PER_RESEED&&(new Date).valueOf()>this._nextReseed?this._REQUIRES_RESEED|this._READY:this._READY:this._poolStrength>=t?this._REQUIRES_RESEED|this._NOT_READY:this._NOT_READY},getProgress:function(t){t=this._PARANOIA_LEVELS[t||this._defaultParanoia];return this._strength>=t||this._poolStrength>t?1:this._poolStrength/t},startCollectors:function(){if(!this._collectorsStarted){if(this._eventListener={loadTimeCollector:this._bind(this._loadTimeCollector),mouseCollector:this._bind(this._mouseCollector),accelerometerCollector:this._bind(this._accelerometerCollector)},window.addEventListener)window.addEventListener("load",this._eventListener.loadTimeCollector,!1),window.addEventListener("mousemove",this._eventListener.mouseCollector,!1),window.addEventListener("devicemotion",this._eventListener.accelerometerCollector,!1);else{if(!document.attachEvent)throw new v.exception.bug("can't attach event");document.attachEvent("onload",this._eventListener.loadTimeCollector),document.attachEvent("onmousemove",this._eventListener.mouseCollector)}this._collectorsStarted=!0}},stopCollectors:function(){this._collectorsStarted&&(window.removeEventListener?(window.removeEventListener("load",this._eventListener.loadTimeCollector,!1),window.removeEventListener("mousemove",this._eventListener.mouseCollector,!1),window.removeEventListener("devicemotion",this._eventListener.accelerometerCollector,!1)):document.detachEvent&&(document.detachEvent("onload",this._eventListener.loadTimeCollector),document.detachEvent("onmousemove",this._eventListener.mouseCollector)),this._collectorsStarted=!1)},addEventListener:function(t,e){this._callbacks[t][this._callbackI++]=e},removeEventListener:function(t,e){var n,o,i=this._callbacks[t],r=[];for(o in i)i.hasOwnProperty(o)&&i[o]===e&&r.push(o);for(n=0;n=1<this._strength&&(this._strength=o),this._reseedCount++,this._reseed(n)},_mouseCollector:function(t){var e=t.x||t.clientX||t.offsetX||0,t=t.y||t.clientY||t.offsetY||0;v.random.addEntropy([e,t],2,"mouse"),this._addCurrentTimeToEntropy(0)},_loadTimeCollector:function(){this._addCurrentTimeToEntropy(2)},_addCurrentTimeToEntropy:function(t){window&&window.performance&&"function"==typeof window.performance.now?v.random.addEntropy(window.performance.now(),t,"loadtime"):v.random.addEntropy((new Date).valueOf(),t,"loadtime")},_accelerometerCollector:function(t){var e,t=t.accelerationIncludingGravity.x||t.accelerationIncludingGravity.y||t.accelerationIncludingGravity.z;window.orientation&&"number"==typeof(e=window.orientation)&&v.random.addEntropy(e,1,"accelerometer"),t&&v.random.addEntropy(t,2,"accelerometer"),this._addCurrentTimeToEntropy(0)},_fireEvent:function(t,e){var n,o=v.random._callbacks[t],i=[];for(n in o)o.hasOwnProperty(n)&&i.push(o[n]);for(n=0;n= 300) {
120 | handleError(_failure, _timer, 'Request error', _rhr.status, _rhr.responseText);
121 | } else {
122 | var jsonResponse;
123 | try {
124 | jsonResponse = JSON.parse(_rhr.responseText);
125 | } catch (e) {
126 | handleError(_failure, _timer, 'Response error (JSON parse failed)', _rhr.status, '{}');
127 | }
128 | _success({
129 | data: jsonResponse,
130 | status: 200
131 | });
132 | }
133 | }
134 | };
135 |
136 | if (!(_rhr = getXhr())) {
137 | handleError(_failure, _timer, 'Browser error (CORS not supported)');
138 | return;
139 | }
140 | _payload = JSON.stringify(_data);
141 | _headers = {
142 | 'Accept': 'application/json',
143 | 'Content-Type': 'application/json',
144 | 'Authorization': 'Basic ' + _auth
145 | };
146 |
147 | if(typeof _method === 'undefined'|| _method===null){
148 | _method = 'POST';
149 | }
150 | _rhr.open(_method, _url, true);
151 |
152 | // set the Credentials flag request header only if there is no
153 | // XHR2 features
154 | // must be set after opening the request to an
155 | // InvalidOperationException in IE
156 | if ('withCredentials' in _rhr) {
157 | _rhr.withCredentials = true;
158 | }
159 |
160 | // apply the request headers
161 | for (var prop in _headers) {
162 | if (_headers.hasOwnProperty(prop) && _headers[prop]) {
163 | if ('setRequestHeader' in _rhr) {
164 | _rhr.setRequestHeader(prop, _headers[prop]);
165 | }
166 | }
167 | }
168 |
169 | // define the onreadystate handler
170 | if ('onreadystatechange' in _rhr) {
171 | _rhr.onreadystatechange = handleResponse;
172 | } else if ('onload' in _rhr && 'onerror' in _rhr) {
173 | _rhr.onload = handleResponse;
174 | _rhr.onerror = handleError;
175 | }
176 |
177 | // set a timeout
178 | _timer = setTimeout(function(){
179 | // reset the handler
180 | if ('onload' in _rhr) {
181 | _rhr.onload = Function.prototype;
182 | } else {
183 | _rhr.onreadystatechange = Function.prototype;
184 | }
185 | _rhr.abort();
186 | _rhr = null;
187 | handleError(_failure, _timer, 'Timeout after ' + _timeout + ' milliseconds');
188 | }, _timeout);
189 |
190 | // make the request
191 | _rhr.send(_payload);
192 | }
193 | };
194 |
195 | function makeBaseAuth(user) {
196 | var tok = user + ':';
197 | var hash = btoa(tok);
198 | return hash;
199 | };
200 |
201 | function getHostname(){
202 | if(_openpay.sandboxMode) {
203 | return _openpay.sandboxHostname;
204 | } else if(_openpay.developMode){
205 | return _openpay.developHostname;
206 | } else {
207 | return _openpay.hostname;
208 | }
209 | }
210 |
211 | return _openpay.version = 1,
212 | _openpay.sandboxMode = false,
213 | _openpay.developMode = false,
214 | _openpay.hostname = "https://api.openpay.mx/v1/",
215 | _openpay.sandboxHostname = "https://sandbox-api.openpay.mx/v1/",
216 | _openpay.developHostname = "https://dev-api.openpay.mx/v1/",
217 | _openpay.Group = {},
218 | _openpay.Update = {},
219 | _openpay.setSandboxMode = function(f) {
220 | _openpay.sandboxMode = (f ? true : false);
221 | if(f){
222 | _openpay.developMode = false;
223 | }
224 | },
225 | _openpay.getSandboxMode = function() {
226 | return _openpay.sandboxMode;
227 | },
228 | _openpay.setDevelopMode = function(f) {
229 | _openpay.developMode = (f ? true : false);
230 | if(f){
231 | _openpay.sandboxMode = false;
232 | }
233 | },
234 | _openpay.getDevelopMode = function() {
235 | return _openpay.developMode;
236 | },
237 | _openpay.setId = function(t) {
238 | _openpay.id = t;
239 | },
240 | _openpay.getId = function() {
241 | return _openpay.id;
242 | },
243 | _openpay.setApiKey = function(t) {
244 | _openpay.key = t;
245 | },
246 | _openpay.getApiKey = function() {
247 | return _openpay.key;
248 | },
249 | _openpay.Group.setId = function(t) {
250 | _openpay.Group.id = t;
251 | },
252 | _openpay.Group.getId = function() {
253 | return _openpay.Group.id;
254 | },
255 | _openpay.Group.setApiKey = function(t) {
256 | _openpay.Group.key = t;
257 | },
258 | _openpay.Group.getApiKey = function() {
259 | return _openpay.Group.key;
260 | },
261 |
262 | _openpay.log = function(_message) {
263 | if (typeof _message === 'object' && 'toString' in _message) {
264 | _message = _message.toString();
265 | }
266 | if (typeof console !== 'undefined' && 'log' in console) {
267 | console.log(_message);
268 | }
269 | },
270 | _openpay.validate = function(_dictionary, _type) {
271 | if (!_dictionary) throw _type + ' required';
272 | if (typeof _dictionary !== 'object') throw _type + ' invalid';
273 | },
274 | _openpay.formatData = function(_dictionary, _validAttributes) {
275 | return _dictionary;
276 | },
277 | _openpay.extractFormInfo = function(form){
278 | var cardFields, objectCard, objectAddress,addressFields;
279 |
280 | var extractForm = function (object) {
281 | if (window.jQuery && object instanceof jQuery) {
282 | return object[0];
283 | } else if (object.nodeType && object.nodeType === 1) {
284 | return object;
285 | } else {
286 | return document.getElementById(object);
287 | }
288 | };
289 |
290 | var findInputsData = function (element, attributeName) {
291 | var found = [],
292 | children = element.children,
293 | child, i;
294 |
295 | for (i = 0; i < children.length; i++) {
296 | child = children[i];
297 |
298 | if (child.nodeType === 1 && child.attributes[attributeName]) {
299 | found.push(child);
300 | } else if (child.children.length > 0) {
301 | found = found.concat(findInputsData(child, attributeName));
302 | }
303 | }
304 |
305 | return found;
306 | };
307 |
308 | var createObject = function (element, attributeName) {
309 | var object = {};
310 |
311 | for (var i = 0; i < element.length; i++) {
312 | fieldName = element[i].attributes[attributeName].value;
313 | inputValue=element[i].value;
314 | if(object[fieldName] !== undefined){
315 | if (!object[fieldName].push) {
316 | object[this.name] = [object[this.name]];
317 | }
318 | object[fieldName].push(inputValue || '');
319 | } else {
320 | object[fieldName] = inputValue || '';
321 | }
322 | }
323 |
324 | return object;
325 | };
326 |
327 | form = extractForm(form);
328 | cardFields = findInputsData(form, 'data-openpay-card');
329 | objectCard = createObject(cardFields, 'data-openpay-card');
330 | addressFields = findInputsData(form, 'data-openpay-card-address');
331 | if(addressFields!== undefined && addressFields.length && addressFields.length > 0){
332 | objectAddress = createObject(addressFields, 'data-openpay-card-address');
333 | if(objectAddress!== undefined){
334 | objectCard["address"] = objectAddress;
335 | }
336 | }
337 | return objectCard;
338 | },
339 |
340 | _openpay.send = function(_endpoint, _data, _success, _failure) {
341 | if (!validateCredentials(_failure, _openpay.id, _openpay.key)) {
342 | return;
343 | }
344 | var _auth = makeBaseAuth(_openpay.key);
345 | var _url = getHostname();
346 | _url = _url + _openpay.id + '/' + _endpoint;
347 | return sendXhr(_url, _auth, _data, _success, _failure);
348 | },
349 |
350 | _openpay.Group.send = function(_endpoint, _data, _success, _failure) {
351 | if (!validateCredentials(_failure, _openpay.Group.id, _openpay.Group.key)) {
352 | return;
353 | }
354 | var _auth = makeBaseAuth(_openpay.Group.key);
355 | var _url = getHostname();
356 | _url = _url + 'groups/' + _openpay.Group.id + '/' + _endpoint;
357 | return sendXhr(_url, _auth, _data, _success, _failure);
358 | },
359 |
360 | _openpay.Update.send = function(_isGruop, _data, _success, _failure, _url){
361 | var _auth = "";
362 | if(_isGruop){
363 | if (!validateCredentials(_failure, _openpay.Group.id, _openpay.Group.key)) {
364 | return;
365 | }
366 | _auth = makeBaseAuth(_openpay.Group.key);
367 | }
368 | else {
369 | if (!validateCredentials(_failure, _openpay.id, _openpay.key)) {
370 | return;
371 | }
372 | _auth = makeBaseAuth(_openpay.key);
373 | }
374 | var url = getHostname()+_url;
375 | return sendXhr(url, _auth, _data, _success, _failure, 'PUT');
376 | },
377 | _openpay;
378 | }.call(this),
379 | INSTANCE = this.OpenPay,
380 | this.OpenPay.card = function(_parent) {
381 | function _card() {
382 | return _card.__super__.constructor.apply(this, arguments);
383 | }
384 | return addProperty(_parent, _card),
385 | _card.validateCardNumber = function(_number) {
386 | return _number = (_number + "").replace(/\s+|-/g, ""), /^\d+$/.test(_number) && _number.length >= 10 && _number.length <= 19
387 | && _card.luhnCheck(_number) && _card.validateCardNumberLength(_number) && _card.validateAcceptCardNumber(_number);
388 | },
389 | _card.validateCVC = function(_cvv_number, _card_number) {
390 | switch (arguments.length) {
391 | case 1:
392 | return _cvv_number = INSTANCE.utils.trim(_cvv_number), /^\d+$/.test(_cvv_number) && _cvv_number.length >= 3 && _cvv_number.length <= 4;
393 | break;
394 |
395 | case 2:
396 | var cardType = _card.cardType(_card_number);
397 | if('American Express' == cardType){
398 | return _cvv_number = INSTANCE.utils.trim(_cvv_number), /^\d+$/.test(_cvv_number) && _cvv_number.length ==4;
399 | }else{
400 | return _cvv_number = INSTANCE.utils.trim(_cvv_number), /^\d+$/.test(_cvv_number) && _cvv_number.length ==3;
401 | }
402 | break;
403 |
404 | default:
405 | return false;
406 | break;
407 | }
408 | },
409 | _card.validateExpiry = function(_month, _year) {
410 | var r, i;
411 | var _year = INSTANCE.utils.trim(_year);
412 | if (_year.length === 2) {
413 | _year = "20"+_year;
414 | }
415 | return _month = INSTANCE.utils.trim(_month), _year, /^\d+$/.test(_month) ? /^\d+$/.test(_year) ?
416 | parseInt(_month, 10) <= 12 && parseInt(_month, 10) >= 1 ? (i = new Date(_year, _month),
417 | r = new Date(), i.setMonth(i.getMonth() - 1), i.setMonth(i.getMonth() + 1, 1), i > r) : !1 : !1 : !1;
418 | },
419 | _card.validateCardNumberLength = function(_number) {
420 | var _cardObj = null;
421 | if (_cardObj = _card.cardAbstract(_number)) {
422 | var _i = _cardObj.length.length;
423 | while (_i--) {
424 | if (_cardObj.length[_i] == _number.length) {
425 | return true;
426 | }
427 | }
428 | return false;
429 | }
430 | return _number.length >= 10 && _number.length <= 19;
431 | },
432 | _card.validateAcceptCardNumber = function(_number) {
433 | return true;
434 | },
435 | _card.luhnCheck = function(_number) {
436 | var n = (_number + "").split(""), digit = 0, sum = parseInt(n[_number.length - 1]);
437 | for (var index = n.length - 2, i = 1; index >= 0; index--, i++) {
438 | digit = parseInt(n[index]);
439 | if (i % 2 != 0) {
440 | digit *= 2;
441 | if (digit > 9) {
442 | digit -= 9;
443 | }
444 | }
445 | sum += digit;
446 | }
447 | return sum % 10 == 0;
448 | },
449 | _card.cardType = function(_number) {
450 | var _cardObj = null;
451 | if (_cardObj = _card.cardAbstract(_number)) {
452 | return _cardObj.name;
453 | }
454 | return '';
455 | },
456 | _card.cardTypes = function() {
457 | return {
458 | 'visa_electron': {
459 | 'name': "Visa Electron",
460 | 'regx': /^(4026|417500|4508|4844|491(3|7))/,
461 | 'length': [ 16 ],
462 | 'accept': true
463 | },
464 | 'visa': {
465 | 'name': "Visa",
466 | 'regx': /^4/,
467 | 'length': [ 16 ],
468 | 'accept': true
469 | },
470 | 'mastercard': {
471 | 'name': "Mastercard",
472 | 'regx': /^5[1-5]/,
473 | 'length': [ 16 ],
474 | 'accept': true
475 | },
476 | 'amex': {
477 | 'name': 'American Express',
478 | 'regx': /^3[47]/,
479 | 'length': [ 15 ],
480 | 'accept': true
481 | },
482 | 'diners_cb': {
483 | 'name': "Diners Club Carte Blanche",
484 | 'regx': /^30[0-5]/,
485 | 'length': [ 14 ],
486 | 'accept': true
487 | },
488 | 'diners_int': {
489 | 'name': "Diners Club International",
490 | 'regx': /^36/,
491 | 'length': [ 14 ],
492 | 'accept': true
493 | },
494 | 'jcb': {
495 | 'name': "JCB",
496 | 'regx': /^35(2[89]|[3-8][0-9])/,
497 | 'length': [ 16 ],
498 | 'accept': true
499 | },
500 | 'laser': {
501 | 'name': "Laser",
502 | 'regx': /^(6304|670[69]|6771)/,
503 | 'length': [ 16, 17, 18, 19 ],
504 | 'accept': true
505 | },
506 | 'maestro': {
507 | 'name': "Maestro",
508 | 'regx': /^(5018|5020|5038|6304|6759|676[1-3])/,
509 | 'length': [ 12, 13, 14, 15, 16, 17, 18, 19 ],
510 | 'accept': true
511 | },
512 | 'discover': {
513 | 'name': "Discover",
514 | 'regx': /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
515 | 'length': [ 16 ],
516 | 'accept': true
517 | }
518 | };
519 | },
520 | _card.cardAbstract = function(_number) {
521 | var _cardTypes = {};
522 | _cardTypes = _card.cardTypes();
523 | for (var _key in _cardTypes) {
524 | var _cardObj = _cardTypes[_key];
525 | if (_number.match(_cardObj.regx)) {
526 | return _cardObj;
527 | }
528 | }
529 | return false;
530 | },
531 | _card.whitelistedAttrs = ["holder_name", "cvv2", "expiration_month", "expiration_year"],
532 | _card.extractFormAndUpdateCard = function(_form, _success, _failure, _customerId, _mycard){
533 | var _params = INSTANCE.extractFormInfo(_form);
534 | return _card.update(_params, _success, _failure, _customerId, _mycard);
535 | },
536 | _card.update = function(_params, _success, _failure, _customerId, _mycard){
537 | var url = "/"+this.getId();
538 | if(typeof _customerId !== 'undefined' && _customerId!==null){
539 | url=url+"/customers/"+_customerId;
540 | }
541 | if(typeof _mycard !== 'undefined' && _mycard!==null){
542 | url=url+"/cards/"+_mycard;
543 | }
544 | return INSTANCE.formatData(_params, _card.whitelistedAttrs), INSTANCE.Update.send(false, _params, _success, _failure, url);
545 | },
546 | _card;
547 |
548 | }.call(this, this.OpenPay),
549 | // Inicio seccion token
550 | this.OpenPay.token = function(_parent){
551 | function _token(){
552 | return _token.__super__.constructor.apply(this, arguments);
553 | }
554 | return addProperty(_parent, _token),
555 | _token.whitelistedAttrs = [ "card_number", "holder_name", "cvv2", "expiration_month", "expiration_year", "address" ],
556 | _token.extractFormAndCreate = function(_form, _success, _failure, _customerId){
557 | var _params = INSTANCE.extractFormInfo(_form);
558 | return _token.create(_params, _success, _failure);
559 | },
560 | _token.create = function(_params, _success, _failure) {
561 | var _endpoint = 'tokens';
562 | return INSTANCE.validate(_params, "tarjeta"), INSTANCE.formatData(_params, _token.whitelistedAttrs), INSTANCE.send(_endpoint, _params, _success, _failure);
563 | }, _token;
564 | }.call(this, this.OpenPay),
565 | // fin seccion token
566 |
567 | // Tokens de Grupos
568 | this.OpenPay.Group.token = function(_parent){
569 | function _token(){
570 | return _token.__super__.constructor.apply(this, arguments);
571 | }
572 | return addProperty(_parent, _token),
573 | _token.whitelistedAttrs = [ "card_number", "holder_name", "cvv2", "expiration_month", "expiration_year", "address" ],
574 | _token.extractFormAndCreate = function(_form, _success, _failure, _customerId){
575 | var _params = INSTANCE.extractFormInfo(_form);
576 | return _token.create(_params, _success, _failure);
577 | },
578 | _token.create = function(_params, _success, _failure) {
579 | var _endpoint = 'tokens';
580 | return INSTANCE.validate(_params, "tarjeta"), INSTANCE.formatData(_params, _token.whitelistedAttrs), INSTANCE.Group.send(_endpoint, _params, _success, _failure);
581 | }, _token;
582 | }.call(this, this.OpenPay),
583 | // fin Tokens de Grupos
584 |
585 | // Modificacion de Grupos
586 | this.OpenPay.Group.card = function(_parent){
587 | function _group(){
588 | return _group.__super__.constructor.apply(this, arguments);
589 | }
590 | return addProperty(_parent, _group),
591 | _group.whitelistedAttrs = ["holder_name", "cvv2", "expiration_month", "expiration_year"],
592 | _group.extractFormAndUpdateCard = function(_form, _success, _failure, _customerId, _mycard){
593 | var _params = INSTANCE.extractFormInfo(_form);
594 | return _group.update(_params, _success, _failure, _customerId, _mycard);
595 | },
596 | _group.update = function(_params, _success, _failure, _customerId, _mycard){
597 | var url = "groups/"+this.Group.id+"/customers/"+_customerId+"/cards/"+_mycard;
598 | if(!_params.merchant_id){
599 | _params.merchant_id = this.getId();
600 | }
601 | return INSTANCE.formatData(_params, _group.whitelistedAttrs), INSTANCE.Update.send(true, _params, _success, _failure, url);
602 | }, _group;
603 | }.call(this, this.OpenPay),
604 | // fin de modificacion de groups
605 |
606 | this.OpenPay.utils = function(_parent) {
607 | function _utils() {}
608 | return addProperty(_parent, _utils),
609 | _utils.trim = function(e) {
610 | return (e + "").replace(/^\s+|\s+$/g, "");
611 | },
612 | _utils.underscore = function(e) {
613 | return (e + "").replace(/([A-Z])/g, function(e) {
614 | return "_" + e.toLowerCase();
615 | }).replace(/-/g, "_");
616 | },
617 | _utils.underscoreKeys = function(e) {
618 | var n, r;
619 | r = [];
620 | for (var t in e) n = e[t], delete e[t], r.push(e[this.underscore(t)] = n);
621 | return r;
622 | },
623 | _utils.isElement = function(e) {
624 | return typeof e != "object" ? !1 : typeof jQuery != "undefined" && jQuery !== null && e instanceof jQuery ? !0 : e.nodeType === 1;
625 | }, _utils;
626 | }.call(this, this.OpenPay),
627 |
628 | // Inicio seccion checkout
629 | this.OpenPay.checkout = function(_parent){
630 | function _checkout(){
631 | return _checkout.__super__.constructor.apply(this, arguments);
632 | }
633 | return addProperty(_parent, _checkout),
634 | _checkout.whitelistedAttrs = [ "amount", "currency", "description", "order_id", "send_email", "customer", "cancel_url", "redirect_url","expiration_date" ],
635 | _checkout.extractFormAndCreate = function(_form, _success, _failure){
636 | var _params = INSTANCE.extractFormInfo(_form);
637 | return _checkout.create(_params, _success, _failure);
638 | },
639 | _checkout.create = function(_params, _success, _failure) {
640 | var _endpoint = 'public-checkouts';
641 | return INSTANCE.formatData(_params, _checkout.whitelistedAttrs), INSTANCE.send(_endpoint, _params, _success, _failure);
642 | }, _checkout;
643 | }.call(this, this.OpenPay),
644 |
645 | typeof module != "undefined" && module !== null && (module.exports = this.OpenPay),
646 | typeof define == "function" && define("openpay", [], function() {
647 | return CALLER.OpenPay;
648 | });
649 | }).call(this);
650 |
651 | /*
652 | * Copyright (c) 2010 Nick Galbreath
653 | * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript
654 | *
655 | * Permission is hereby granted, free of charge, to any person obtaining a copy
656 | * of this software and associated documentation files (the "Software"), to deal
657 | * in the Software without restriction, including without limitation the rights
658 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
659 | * copies of the Software, and to permit persons to whom the Software is
660 | * furnished to do so, subject to the following conditions:
661 | *
662 | * The above copyright notice and this permission notice shall be included in
663 | * all copies or substantial portions of the Software.
664 | *
665 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
666 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
667 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
668 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
669 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
670 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
671 | * SOFTWARE.
672 | */
673 |
674 | /*
675 | * base64 encode/decode compatible with window.btoa/atob
676 | *
677 | * window.atob/btoa is a Firefox extension to convert binary data (the "b") to
678 | * base64 (ascii, the "a").
679 | *
680 | * It is also found in Safari and Chrome. It is not available in IE.
681 | *
682 | * if (!window.btoa) window.btoa = base64.encode if (!window.atob) window.atob =
683 | * base64.decode
684 | *
685 | * The original spec's for atob/btoa are a bit lacking
686 | * https://developer.mozilla.org/en/DOM/window.atob
687 | * https://developer.mozilla.org/en/DOM/window.btoa
688 | *
689 | * window.btoa and base64.encode takes a string where charCodeAt is [0,255] If
690 | * any character is not [0,255], then an DOMException(5) is thrown.
691 | *
692 | * window.atob and base64.decode take a base64-encoded string If the input
693 | * length is not a multiple of 4, or contains invalid characters then an
694 | * DOMException(5) is thrown.
695 | */
696 | var base64 = {};
697 | base64.PADCHAR = '=';
698 | base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
699 |
700 | base64.makeDOMException = function() {
701 | // sadly in FF,Safari,Chrome you can't make a DOMException
702 | var e, tmp;
703 |
704 | try {
705 | return new DOMException(DOMException.INVALID_CHARACTER_ERR);
706 | } catch (tmp) {
707 | // not available, just passback a duck-typed equiv
708 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error
709 | // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype
710 | var ex = new Error("DOM Exception 5");
711 |
712 | // ex.number and ex.description is IE-specific.
713 | ex.code = ex.number = 5;
714 | ex.name = ex.description = "INVALID_CHARACTER_ERR";
715 |
716 | // Safari/Chrome output format
717 | ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; };
718 | return ex;
719 | }
720 | }
721 |
722 | base64.getbyte64 = function(s,i) {
723 | // This is oddly fast, except on Chrome/V8.
724 | // Minimal or no improvement in performance by using a
725 | // object with properties mapping chars to value (eg. 'A': 0)
726 | var idx = base64.ALPHA.indexOf(s.charAt(i));
727 | if (idx === -1) {
728 | throw base64.makeDOMException();
729 | }
730 | return idx;
731 | }
732 |
733 | base64.decode = function(s) {
734 | // convert to string
735 | s = '' + s;
736 | var getbyte64 = base64.getbyte64;
737 | var pads, i, b10;
738 | var imax = s.length
739 | if (imax === 0) {
740 | return s;
741 | }
742 |
743 | if (imax % 4 !== 0) {
744 | throw base64.makeDOMException();
745 | }
746 |
747 | pads = 0
748 | if (s.charAt(imax - 1) === base64.PADCHAR) {
749 | pads = 1;
750 | if (s.charAt(imax - 2) === base64.PADCHAR) {
751 | pads = 2;
752 | }
753 | // either way, we want to ignore this last block
754 | imax -= 4;
755 | }
756 |
757 | var x = [];
758 | for (i = 0; i < imax; i += 4) {
759 | b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) |
760 | (getbyte64(s,i+2) << 6) | getbyte64(s,i+3);
761 | x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff));
762 | }
763 |
764 | switch (pads) {
765 | case 1:
766 | b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6);
767 | x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff));
768 | break;
769 | case 2:
770 | b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12);
771 | x.push(String.fromCharCode(b10 >> 16));
772 | break;
773 | }
774 | return x.join('');
775 | }
776 |
777 | base64.getbyte = function(s,i) {
778 | var x = s.charCodeAt(i);
779 | if (x > 255) {
780 | throw base64.makeDOMException();
781 | }
782 | return x;
783 | }
784 |
785 | base64.encode = function(s) {
786 | if (arguments.length !== 1) {
787 | throw new SyntaxError("Not enough arguments");
788 | }
789 | var padchar = base64.PADCHAR;
790 | var alpha = base64.ALPHA;
791 | var getbyte = base64.getbyte;
792 |
793 | var i, b10;
794 | var x = [];
795 |
796 | // convert to string
797 | s = '' + s;
798 |
799 | var imax = s.length - s.length % 3;
800 |
801 | if (s.length === 0) {
802 | return s;
803 | }
804 | for (i = 0; i < imax; i += 3) {
805 | b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2);
806 | x.push(alpha.charAt(b10 >> 18));
807 | x.push(alpha.charAt((b10 >> 12) & 0x3F));
808 | x.push(alpha.charAt((b10 >> 6) & 0x3f));
809 | x.push(alpha.charAt(b10 & 0x3f));
810 | }
811 | switch (s.length - imax) {
812 | case 1:
813 | b10 = getbyte(s,i) << 16;
814 | x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
815 | padchar + padchar);
816 | break;
817 | case 2:
818 | b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8);
819 | x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
820 | alpha.charAt((b10 >> 6) & 0x3f) + padchar);
821 | break;
822 | }
823 | return x.join('');
824 | };
825 |
826 | (function (){
827 | if (!window.btoa) {
828 | window.btoa = base64.encode
829 | }
830 | if (!window.atob){
831 | window.atob = base64.decode
832 | }
833 | })();
834 |
835 | /* jsonp.js, (c) Przemek Sobstel 2012, License: MIT */
836 |
837 | var $jsonp = (function(){
838 | var that = {};
839 |
840 | that.send = function(request) {
841 | var requestID = new Date().getTime();
842 | var callbackName = request.callbackName || 'callback',
843 | on_success = request.onSuccess || function(){},
844 | on_error = request.onError || function(){},
845 | timeout = request.timeout || 4000,
846 | url = request.url || '',
847 | data = request.data || {}
848 | dataIdName = "idData";
849 | var e = encodeURIComponent;
850 | data.callback = "var "+dataIdName+"="+ (++requestID)+";"+callbackName;
851 | window[dataIdName]=undefined;
852 | var toCamelCase = function(string) {
853 | string = string.replace(/[\-_\s]+(.)?/g, function(match, chr) {
854 | return chr ? chr.toUpperCase() : '';
855 | });
856 | return string.replace(/^([A-Z])/, function(match, chr) {
857 | return chr ? chr.toLowerCase() : '';
858 | });
859 | };
860 |
861 | var serializeData = function(object, result, scope) {
862 | var key, value;
863 |
864 | if (result == null) {
865 | result = [];
866 | }
867 | for (key in object) {
868 | value = object[key];
869 | if (scope) {
870 | key = "" + scope + "." + key;
871 | }
872 | if (typeof value === 'object') {
873 | serializeData(value, result, key);
874 | } else {
875 | result.push(toCamelCase(""+ key) + "=" + (e(value)));
876 | }
877 | }
878 | return result.join('&').replace(/%20/g, '+');
879 | };
880 |
881 | timeout_trigger = window.setTimeout(function(){
882 | window[callbackName] = function(){};
883 | on_error('Timeout after ' + timeout + ' milliseconds');
884 | }, timeout );
885 |
886 | var script = document.createElement('script');
887 | script.type = 'text/javascript';
888 | script.async = true;
889 | script.src = url + '?' + serializeData(data);
890 |
891 | var removeScript = function(){
892 | var _ref;
893 | if ((_ref = script.parentNode) != null) {
894 | _ref.removeChild(script);
895 | }
896 | };
897 |
898 | var abort = function(){
899 | window.clearTimeout(timeout_trigger);
900 | removeScript();
901 | on_error("There was an error, please verify your authentication data or conection.");
902 | };
903 |
904 | if ('onreadystatechange' in script) {
905 | script.onreadystatechange=function(){
906 | if(script.readyState == "loaded"){
907 | if (typeof window[dataIdName] === "undefined") {
908 | abort();
909 | }
910 | }
911 | };
912 | } else if ('onerror' in script) {
913 | script.onerror= function(){
914 | abort();
915 | };
916 | }
917 |
918 | window[callbackName] = function(data){
919 | window.clearTimeout(timeout_trigger);
920 | removeScript();
921 | on_success(data);
922 | };
923 | document.getElementsByTagName('head')[0].appendChild(script);
924 | };
925 |
926 | return that;
927 | })();
928 | if (typeof jQuery !== 'undefined') {
929 | (function( $ ) {
930 | if (typeof $ !== 'undefined') {
931 |
932 | $.fn.cardNumberInput = function() {
933 | return $(this).restrictedInput('card');
934 | };
935 |
936 | $.fn.numericInput = function() {
937 | return $(this).restrictedInput('numeric');
938 | };
939 |
940 | $.fn.restrictedInput = function(type) {
941 | var
942 | $this = $(this),
943 | cards = [
944 | {
945 | 'type' : 'amex',
946 | 'regex' : /^3[47]/,
947 | 'format' : /(\d{1,4})(\d{1,6})?(\d{1,5})?/,
948 | 'length' : 15
949 | },
950 | {
951 | 'type' : 'other',
952 | 'format' : /(\d{1,4})/g,
953 | 'length' : 16
954 | }
955 | ],
956 | gcard = function(num) {
957 | var
958 | card,
959 | i;
960 |
961 | num = ((num + '').replace(/\D/g, ''));
962 | for (i = 0; i < cards.length; i++) {
963 | card = cards[i];
964 | if (card['regex'] && card['regex'].test(num)) {
965 | return card;
966 | }
967 | }
968 | },
969 | rstnmb = function(e) {
970 | var inp;
971 | if (e.metaKey || e.ctrlKey) {
972 | return true;
973 | } else if (e.which === 0) {
974 | return true;
975 | } else if (e.which === 32) {
976 | return false;
977 | } else if (e.which < 33) {
978 | return true;
979 | }
980 |
981 | inp = String.fromCharCode(e.which);
982 | return !!/[\d\s]/.test(inp);
983 | },
984 | onmb = function(e) {
985 | var
986 | $t = $(e.currentTarget),
987 | val = (($t.val() + String.fromCharCode(e.which)).replace(/\D/g, '')),
988 | card,
989 | isN;
990 |
991 | isN = rstnmb(e);
992 | card = gcard(val);
993 | if (card) {
994 | return isN && val.length <= card['length'];
995 | }
996 | return isN && val.length <= 16;
997 | },
998 | refrmnmb = function(e) {
999 | var
1000 | $t = $(e.currentTarget),
1001 | val = $t.val();
1002 |
1003 | if (e.which !== 8) {
1004 | return;
1005 | }
1006 |
1007 | if (/\d\s$/.test(val)) {
1008 | e.preventDefault();
1009 | return setTimeout(function() {
1010 | return $t.val(val.replace(/\d\s$/, ''));
1011 | });
1012 | } else if (/\s\d?$/.test(val)) {
1013 | e.preventDefault();
1014 | return setTimeout(function() {
1015 | return $t.val(val.replace(/\s\d?$/, ''));
1016 | });
1017 | }
1018 | },
1019 | frmnmb = function(e) {
1020 | var
1021 | $t = $(e.currentTarget),
1022 | val = $t.val(),
1023 | digit = String.fromCharCode(e.which),
1024 | length = (val.replace(/\D/g, '') + digit).length,
1025 | upl = 16,
1026 | card = gcard(val + digit),
1027 | re;
1028 |
1029 | if (!/^\d+$/.test(digit)) {
1030 | return;
1031 | }
1032 |
1033 | if (card) {
1034 | upl = card['length'];
1035 | }
1036 |
1037 | if (length >= upl) {
1038 | return;
1039 | }
1040 |
1041 | if (card && card['type'] === 'amex') {
1042 | re = /^(\d{4}|\d{4}\s\d{6})$/;
1043 | } else {
1044 | re = /(?:^|\s)(\d{4})$/;
1045 | }
1046 |
1047 | if (re.test(val)) {
1048 | e.preventDefault();
1049 | return setTimeout(function() {
1050 | return $t.val(val + ' ' + digit);
1051 | });
1052 | } else if (re.test(val + digit)) {
1053 | e.preventDefault();
1054 | return setTimeout(function() {
1055 | return $t.val(val + digit + ' ');
1056 | });
1057 | }
1058 | };
1059 |
1060 | if ('card' === type) {
1061 | $this
1062 | .on('keypress', onmb)
1063 | .on('keypress', frmnmb)
1064 | .on('keydown', refrmnmb)
1065 | .on('paste', onmb)
1066 | .on('paste', frmnmb)
1067 | .on('change', frmnmb)
1068 | .on('input', frmnmb);
1069 | } else if ('numeric' === type) {
1070 | $this
1071 | .on('keypress', rstnmb)
1072 | .on('paste', rstnmb)
1073 | .on('change', rstnmb)
1074 | .on('input', rstnmb);
1075 | }
1076 | return this;
1077 | };
1078 | }
1079 | })( jQuery );
1080 | }
1081 |
--------------------------------------------------------------------------------
/lib/openpay.v1.min.js:
--------------------------------------------------------------------------------
1 | /*! openpay.js v1.2.39 2023-07-25 */
2 | !function(){var u,a={}.hasOwnProperty,n=function(e,t){function n(){this.constructor=t}for(var r in e)a.call(e,r)&&(t[r]=e[r]);return n.prototype=e.prototype,t.prototype=new n,t.__super__=e.prototype,t},e=this;this.OpenPay=function(){function f(){}function h(e,t,n,r,a){clearTimeout(t);t=null;n=n||"Unknown error",r=r||0,a=a||"{}";try{t=JSON.parse(a)}catch(o){n="Response error"}e({message:n,status:r,data:t,toString:function(){return this.message+" [status "+this.status+"]"}})}function i(e,t,n){if(void 0!==t&&/^[a-z0-9]+$/i.test(t)){if(void 0!==n&&/^pk_[a-z0-9]+$/i.test(n))return 1;h(e,null,"Empty or invalid Openpay API Key")}else h(e,null,"Empty or invalid Openpay ID")}function u(e,t,n,r,a,o){var i,u=null,s=null,c={};if("function"!=typeof r&&(r=f.log),"function"!=typeof a&&(a=f.log),"undefined"==typeof JSON)h(a,s,"Browser error (JSON library not found)");else{var d,p=XMLHttpRequest&&"withCredentials"in new XMLHttpRequest;if(p){function d(){if("undefined"!=typeof u.readyState&&4==u.readyState||!p)if(clearTimeout(s),u.status<200||300<=u.status)h(a,s,"Request error",u.status,u.responseText);else{var e;try{e=JSON.parse(u.responseText)}catch(t){h(a,s,"Response error (JSON parse failed)",u.status,"{}")}r({data:e,status:200})}}if(u=function(){if(e=window,"function"==(n=typeof e[t="XMLHttpRequest"])||"object"==n&&e[t]||"unknown"==n)return new XMLHttpRequest;var e,t,n}()){for(var l in i=JSON.stringify(n),c={Accept:"application/json","Content-Type":"application/json",Authorization:"Basic "+t},u.open(o=null==o?"POST":o,e,!0),"withCredentials"in u&&(u.withCredentials=!0),c)c.hasOwnProperty(l)&&c[l]&&"setRequestHeader"in u&&u.setRequestHeader(l,c[l]);"onreadystatechange"in u?u.onreadystatechange=d:"onload"in u&&"onerror"in u&&(u.onload=d,u.onerror=h),s=setTimeout(function(){"onload"in u?u.onload=Function.prototype:u.onreadystatechange=Function.prototype,u.abort(),u=null,h(a,s,"Timeout after 40000 milliseconds")},4e4),u.send(i)}else h(a,s,"Browser error (CORS not supported)")}else"undefined"!=typeof XDomainRequest?(n.apiKey=t,$jsonp.send({callbackName:"getResultData",onSuccess:d=function(e){e.error?h(a,s,"Request error",e.httpStatus,JSON.stringify(e)):r({data:e.data,status:200})},onError:h,timeout:4e4,url:e+"/jsonp",data:n})):h(a,s,"Browser error (CORS not supported)")}}function s(e){return btoa(e+":")}function c(){return f.sandboxMode?f.sandboxHostname:f.developMode?f.developHostname:f.hostname}return f.version=1,f.sandboxMode=!1,f.developMode=!1,f.hostname="https://api.openpay.mx/v1/",f.sandboxHostname="https://sandbox-api.openpay.mx/v1/",f.developHostname="https://dev-api.openpay.mx/v1/",f.Group={},f.Update={},f.setSandboxMode=function(e){f.sandboxMode=!!e,e&&(f.developMode=!1)},f.getSandboxMode=function(){return f.sandboxMode},f.setDevelopMode=function(e){f.developMode=!!e,e&&(f.sandboxMode=!1)},f.getDevelopMode=function(){return f.developMode},f.setId=function(e){f.id=e},f.getId=function(){return f.id},f.setApiKey=function(e){f.key=e},f.getApiKey=function(){return f.key},f.Group.setId=function(e){f.Group.id=e},f.Group.getId=function(){return f.Group.id},f.Group.setApiKey=function(e){f.Group.key=e},f.Group.getApiKey=function(){return f.Group.key},f.log=function(e){"object"==typeof e&&"toString"in e&&(e=e.toString()),"undefined"!=typeof console&&"log"in console&&console.log(e)},f.validate=function(e,t){if(!e)throw t+" required";if("object"!=typeof e)throw t+" invalid"},f.formatData=function(e,t){return e},f.extractFormInfo=function(e){var t,i=function(e,t){for(var n,r=[],a=e.children,o=0;o>16,n>>8&255,255&n));switch(t){case 1:n=r(e,i)<<18|r(e,i+1)<<12|r(e,i+2)<<6,o.push(String.fromCharCode(n>>16,n>>8&255));break;case 2:n=r(e,i)<<18|r(e,i+1)<<12,o.push(String.fromCharCode(n>>16))}return o.join("")},getbyte:function(e,t){t=e.charCodeAt(t);if(255>18)),i.push(a.charAt(n>>12&63)),i.push(a.charAt(n>>6&63)),i.push(a.charAt(63&n));switch(e.length-u){case 1:n=o(e,t)<<16,i.push(a.charAt(n>>18)+a.charAt(n>>12&63)+r+r);break;case 2:n=o(e,t)<<16|o(e,t+1)<<8,i.push(a.charAt(n>>18)+a.charAt(n>>12&63)+a.charAt(n>>6&63)+r)}return i.join("")}},$jsonp=(window.btoa||(window.btoa=base64.encode),window.atob||(window.atob=base64.decode),function(){var e={send:function(e){var t=(new Date).getTime(),n=e.callbackName||"callback",r=e.onSuccess||function(){},a=e.onError||function(){},o=e.timeout||4e3,i=e.url||"",e=e.data||{},u=(dataIdName="idData",encodeURIComponent),s=(e.callback="var "+dataIdName+"="+ ++t+";"+n,window[dataIdName]=undefined,function(e,t,n){var r,a;for(r in null==t&&(t=[]),e)a=e[r],n&&(r=n+"."+r),"object"==typeof a?s(a,t,r):t.push((""+r).replace(/[\-_\s]+(.)?/g,function(e,t){return t?t.toUpperCase():""}).replace(/^([A-Z])/,function(e,t){return t?t.toLowerCase():""})+"="+u(a));return t.join("&").replace(/%20/g,"+")}),c=(timeout_trigger=window.setTimeout(function(){window[n]=function(){},a("Timeout after "+o+" milliseconds")},o),document.createElement("script")),d=(c.type="text/javascript",c["async"]=!0,c.src=i+"?"+s(e),function(){var e;null!=(e=c.parentNode)&&e.removeChild(c)}),p=function(){window.clearTimeout(timeout_trigger),d(),a("There was an error, please verify your authentication data or conection.")};"onreadystatechange"in c?c.onreadystatechange=function(){"loaded"==c.readyState&&"undefined"==typeof window[dataIdName]&&p()}:"onerror"in c&&(c.onerror=function(){p()}),window[n]=function(e){window.clearTimeout(timeout_trigger),d(),r(e)},document.getElementsByTagName("head")[0].appendChild(c)}};return e}());"undefined"!=typeof jQuery&&!function(s){void 0!==s&&(s.fn.cardNumberInput=function(){return s(this).restrictedInput("card")},s.fn.numericInput=function(){return s(this).restrictedInput("numeric")},s.fn.restrictedInput=function(e){var t=s(this),r=[{type:"amex",regex:/^3[47]/,format:/(\d{1,4})(\d{1,6})?(\d{1,5})?/,length:15},{type:"other",format:/(\d{1,4})/g,length:16}],u=function(e){var t,n;for(e=(e+"").replace(/\D/g,""),n=0;n
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
22 |
64 |
65 |