mirror of
https://github.com/valitydev/checkout.git
synced 2024-11-06 02:25:18 +00:00
Merge branch 'master' into ft/FE-58/payformIntegration
This commit is contained in:
commit
b3f920c801
@ -21,6 +21,7 @@
|
||||
"no-useless-computed-key": 2,
|
||||
"no-useless-constructor": 2,
|
||||
"no-useless-rename": 2,
|
||||
"prefer-template": 2
|
||||
"prefer-template": 2,
|
||||
"no-console": 0
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import source from 'vinyl-source-stream';
|
||||
import eslint from 'gulp-eslint';
|
||||
import livereload from 'gulp-livereload';
|
||||
import pug from 'gulp-pug';
|
||||
import nodemon from 'gulp-nodemon';
|
||||
import concat from 'gulp-concat';
|
||||
|
||||
const config = {
|
||||
payframeDist: 'dist/payframe',
|
||||
@ -18,7 +20,7 @@ gulp.task('lint', () => {
|
||||
.pipe(eslint.format());
|
||||
});
|
||||
|
||||
gulp.task('bundlePayframe', ['lint'], () => {
|
||||
gulp.task('bundlePayframe', () => {
|
||||
return browserify({
|
||||
entries: 'src/payframe/payframe.js',
|
||||
extensions: ['.js'],
|
||||
@ -29,7 +31,7 @@ gulp.task('bundlePayframe', ['lint'], () => {
|
||||
.pipe(livereload());
|
||||
});
|
||||
|
||||
gulp.task('bundlePayform', ['lint'], () => {
|
||||
gulp.task('bundlePayform', () => {
|
||||
return browserify({
|
||||
entries: 'src/payform/payform.js',
|
||||
extensions: ['.js'],
|
||||
@ -56,14 +58,15 @@ gulp.task('copyPayframeStyles', () => {
|
||||
});
|
||||
|
||||
gulp.task('copyPayformStyles', () => {
|
||||
return gulp.src('src/payform/payform.css')
|
||||
return gulp.src('src/payform/styles/**/*.css')
|
||||
.pipe(concat('payform.css'))
|
||||
.pipe(gulp.dest(config.payformDist))
|
||||
.pipe(livereload());
|
||||
});
|
||||
|
||||
gulp.task('copyPayformImages', () => {
|
||||
return gulp.src('src/payform/**/*.png')
|
||||
.pipe(gulp.dest(config.payformDist))
|
||||
return gulp.src('src/payform/images/**/*')
|
||||
.pipe(gulp.dest(`${config.payformDist}/images`))
|
||||
.pipe(livereload());
|
||||
});
|
||||
|
||||
@ -76,10 +79,14 @@ gulp.task('runPayform', () => {
|
||||
});
|
||||
|
||||
gulp.task('runSample', () => {
|
||||
connect.server({
|
||||
root: 'sample',
|
||||
host: '127.0.0.1',
|
||||
port: 7051
|
||||
var started = false;
|
||||
return nodemon({
|
||||
script: 'sample/backend.js'
|
||||
}).on('start', () => {
|
||||
if (!started) {
|
||||
cb();
|
||||
started = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -90,7 +97,7 @@ gulp.task('watch', () => {
|
||||
gulp.watch('src/payform/payform.pug', ['buildTemplate']);
|
||||
gulp.watch('src/**/*.css', ['copyPayformStyles']);
|
||||
gulp.watch('src/**/*.css', ['copyPayframeStyles']);
|
||||
gulp.watch('src/**/*.png', ['copyPayformImages']);
|
||||
gulp.watch('src/payform/images/**/*', ['copyPayformImages']);
|
||||
});
|
||||
|
||||
gulp.task('build', ['bundlePayframe', 'bundlePayform', 'buildTemplate', 'copyPayformStyles', 'copyPayframeStyles', 'copyPayformImages']);
|
||||
|
@ -12,15 +12,21 @@
|
||||
"author": "rbkmoney",
|
||||
"license": "",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"whatwg-fetch": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-preset-es2015": "^6.16.0",
|
||||
"babel-register": "^6.16.3",
|
||||
"babelify": "^7.3.0",
|
||||
"browserify": "^13.1.0",
|
||||
"express": "^4.14.0",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-connect": "^5.0.0",
|
||||
"gulp-eslint": "^3.0.1",
|
||||
"gulp-livereload": "^3.8.1",
|
||||
"gulp-nodemon": "^2.1.0",
|
||||
"gulp-pug": "^3.1.0",
|
||||
"vinyl-source-stream": "^1.1.0"
|
||||
}
|
||||
|
44
sample/backend.js
Normal file
44
sample/backend.js
Normal file
@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const router = express.Router();
|
||||
|
||||
app.use((req, res, next) => {
|
||||
res.header('Access-Control-Allow-Methods', 'PUT');
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, X-Request-ID');
|
||||
next();
|
||||
});
|
||||
|
||||
router.route('/processing/payment_tools').post((req, res) => res.json({
|
||||
token: 'token',
|
||||
session: 'sessionToken'
|
||||
}));
|
||||
|
||||
router.route('/init_endpoint').post((req, res) => {
|
||||
res.send('Ok');
|
||||
});
|
||||
|
||||
router.route('/events_endpoint').get((req, res) => {
|
||||
res.json([
|
||||
{
|
||||
id: 1,
|
||||
createdAt: 'datetime',
|
||||
eventType: 'paymentStatusChanged',
|
||||
status: 'pending'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
createdAt: 'datetime',
|
||||
eventType: 'invoiceStatusChanged',
|
||||
status: 'paid'
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
app.use('/', router);
|
||||
|
||||
app.use('/', express.static(__dirname + '/public'));
|
||||
|
||||
app.listen(7051);
|
@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Sample</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
26
sample/public/index.html
Normal file
26
sample/public/index.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<!--<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"-->
|
||||
<!--data-key="pk_test_6pRNASCoBOKtIshFeQd4XMUh"-->
|
||||
<!--data-amount="999"-->
|
||||
<!--data-name="Stripe.com"-->
|
||||
<!--data-description="Widget"-->
|
||||
<!--data-image="https://stripe.com/img/documentation/checkout/marketplace.png"-->
|
||||
<!--data-locale="auto"-->
|
||||
<!--data-zip-code="true">-->
|
||||
<!--</script>-->
|
||||
|
||||
<script src="http://127.0.0.1:7050/payframe/payframe.js" class="rbkmoney-payform"
|
||||
data-key="eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJUdEZzelc3NDB2NTQ1MThVUVg1MGNnczN1U2pCSXkxbDdGcDVyMHdmYzFrIn0.eyJqdGkiOiJjODBhZjlmYi0yNzY5LTQ2YWItOTg4NC0wZWQ0YTVmMjRiOTYiLCJleHAiOjAsIm5iZiI6MCwiaWF0IjoxNDc1MTMxNjAwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjMxMjQ1L2F1dGgvcmVhbG1zL2V4dGVybmFsIiwiYXVkIjoidG9rZW5pemVyIiwic3ViIjoiNGQxMmQyMTMtZWU1ZS00ZWEzLTg2YTYtMDc5ZjZkNDM3NWExIiwidHlwIjoiT2ZmbGluZSIsImF6cCI6InRva2VuaXplciIsIm5vbmNlIjoiMGUzYTU2ZmQtZGUxNy00NTI1LTgxNmYtNjM1YTEzNWJlYTYwIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiNDU3MWE0NjQtYmRjYi00YTkyLTg2ZjQtYWI5YjExYzgyNjE5IiwiY2xpZW50X3Nlc3Npb24iOiI0OTU1MWE3ZC04NGNiLTQxZTUtOTQ2OC0wZmQ3ZDg5ZGYxZmUiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiXX0sInJlc291cmNlX2FjY2VzcyI6eyJjb21tb24tYXBpIjp7InJvbGVzIjpbInBheW1lbnRfdG9vbF90b2tlbnM6Y3JlYXRlIl19fX0.ZayOtPaUNxDfBZh_t8IfTUNOJ8653v2lkNX3pDBEyQV28EGf8qbIFJRtA7LbGwdd8brhRIWLk2XBco7RZUX_GYVHIlRo0IvGAzyLYozjXWdfZHaTkChCpk6QnTCTgYeFxTMbgtYYBXOS7oT0tmQZY-N3O0cuIeBItGU8lzaNqfwH9i61WETZKkHYQ_wL28Kbip9IDSgxqDUWnohDA3ee5QROiw-J0DU8MmEkKBSC4owPkYQTFCJr4A69_3hsXArSh3xYu6gkbHoS3CWXMPMtbpFrSrZG191aRwV9ZQIouzd5jKsk6IRiPVhAWSWayd44qRYTgugMX3Tz06O1hOXkDg"
|
||||
data-invoice-id="e213ed1"
|
||||
data-endpoint-init="http://127.0.0.1:7051/init_endpoint"
|
||||
data-endpoint-events="http://127.0.0.1:7051/events_endpoint">
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
64
src/payform/backend-communication/EventPoller.js
Normal file
64
src/payform/backend-communication/EventPoller.js
Normal file
@ -0,0 +1,64 @@
|
||||
export default class EventPoller {
|
||||
|
||||
static pollEvents(endpointUrl, invoiceId, timeout) {
|
||||
return new Promise((resolve, reject) => {
|
||||
(function poll(self) {
|
||||
setTimeout(() => {
|
||||
self.requestToEndpoint(endpointUrl, invoiceId).then(events => {
|
||||
if (self.isSuccess(events)) {
|
||||
resolve();
|
||||
} else if (self.isError()) {
|
||||
reject();
|
||||
} else {
|
||||
poll(self);
|
||||
}
|
||||
});
|
||||
}, timeout);
|
||||
})(this);
|
||||
});
|
||||
}
|
||||
|
||||
static requestToEndpoint(endpointUrl, invoiceId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(this.buildUrl(endpointUrl, invoiceId), {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(response => {
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
resolve(response.json());
|
||||
} else {
|
||||
reject(response.json());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
static buildUrl(endpointUrl, invoiceId) {
|
||||
const url = new URL(endpointUrl);
|
||||
url.searchParams.append('invoiceId', invoiceId);
|
||||
return url;
|
||||
}
|
||||
|
||||
static isSuccess(events) {
|
||||
const last = this.getLastEvent(events);
|
||||
return (last && last.eventType === 'invoiceStatusChanged' && last.status === 'paid');
|
||||
}
|
||||
|
||||
static isError(events) {
|
||||
const last = this.getLastEvent(events);
|
||||
let result = false;
|
||||
if (last) {
|
||||
const isPaymentFailed = (last.eventType === 'paymentStatusChanged' && last.status === 'failed');
|
||||
const isInvoiceFailed = (last.eventType === 'invoiceStatusChanged' && (last.status === 'cancelled' || last.status === 'unpaid'));
|
||||
result = isPaymentFailed || isInvoiceFailed;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static getLastEvent(events) {
|
||||
return events && events.length > 0 ? events[events.length - 1] : null;
|
||||
}
|
||||
}
|
20
src/payform/backend-communication/Initialization.js
Normal file
20
src/payform/backend-communication/Initialization.js
Normal file
@ -0,0 +1,20 @@
|
||||
export default class Initialization {
|
||||
|
||||
static sendInit(endpoint, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
}).then(response => {
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
resolve();
|
||||
} else {
|
||||
response.json().then(error => reject(error));
|
||||
}
|
||||
}).catch(() => reject('Error send to init endpoint'));
|
||||
});
|
||||
}
|
||||
}
|
23
src/payform/builders/RequestBuilder.js
Normal file
23
src/payform/builders/RequestBuilder.js
Normal file
@ -0,0 +1,23 @@
|
||||
export default class RequestBuilder {
|
||||
|
||||
static buildTokenizationRequest(cardHolder, cardNumber, expDate, cvv) {
|
||||
return {
|
||||
paymentToolType: 'cardData',
|
||||
cardHolder: cardHolder,
|
||||
cardNumber: cardNumber,
|
||||
expDate: expDate,
|
||||
cvv: cvv
|
||||
}
|
||||
}
|
||||
|
||||
static buildInitRequest(invoiceId, token, email) {
|
||||
return {
|
||||
invoiceId: invoiceId,
|
||||
token: token.token,
|
||||
session: token.session,
|
||||
contractInfo: {
|
||||
email: email
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
14
src/payform/elements/Checkmark.js
Normal file
14
src/payform/elements/Checkmark.js
Normal file
@ -0,0 +1,14 @@
|
||||
export default class Checkmark {
|
||||
constructor() {
|
||||
this.element = document.querySelector('.checkmark');
|
||||
this.hide();
|
||||
}
|
||||
|
||||
show() {
|
||||
this.element.style.display = 'block';
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.element.style.display = 'none';
|
||||
}
|
||||
}
|
71
src/payform/elements/Form.js
Normal file
71
src/payform/elements/Form.js
Normal file
@ -0,0 +1,71 @@
|
||||
export default class Form {
|
||||
constructor() {
|
||||
this.element = document.querySelector('#payform');
|
||||
|
||||
this.email = $('#email');
|
||||
this.cardHolder = $('#card-holder');
|
||||
|
||||
this.cardNumber = $('#card-number');
|
||||
this.cardNumber.payment('formatCardNumber');
|
||||
|
||||
this.expDate = $('#exp-date');
|
||||
this.expDate.payment('formatCardExpiry');
|
||||
|
||||
this.cvv = $('#cvv');
|
||||
this.cvv.payment('formatCardCVC');
|
||||
|
||||
$.fn.toggleInputError = function (isError) {
|
||||
this.parent('.payform--group').toggleClass('payform--field__error', isError);
|
||||
};
|
||||
}
|
||||
|
||||
show() {
|
||||
this.element.style.display = 'block';
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.element.style.display = 'none';
|
||||
}
|
||||
|
||||
getEmail() {
|
||||
return this.email.val();
|
||||
}
|
||||
|
||||
getCardHolder() {
|
||||
return this.cardHolder.val();
|
||||
}
|
||||
|
||||
getCardNumber() {
|
||||
return this.cardNumber.val();
|
||||
}
|
||||
|
||||
validateCardNumber() {
|
||||
const isValid = $.payment.validateCardNumber(this.getCardNumber());
|
||||
this.cardNumber.toggleInputError(!isValid);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
getExpDate() {
|
||||
return this.expDate.val();
|
||||
}
|
||||
|
||||
validateExpDate() {
|
||||
const isValid = $.payment.validateCardExpiry(this.getExpDate());
|
||||
this.expDate.toggleInputError(!isValid);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
getCvv() {
|
||||
return this.cvv.val();
|
||||
}
|
||||
|
||||
validateCvv() {
|
||||
const isValid = $.payment.validateCardCVC(this.getCvv());
|
||||
this.expDate.toggleInputError(!isValid);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
validate() {
|
||||
return this.validateCardNumber() && this.validateExpDate() && this.validateCvv();
|
||||
}
|
||||
}
|
14
src/payform/elements/Spinner.js
Normal file
14
src/payform/elements/Spinner.js
Normal file
@ -0,0 +1,14 @@
|
||||
export default class Spinner {
|
||||
constructor() {
|
||||
this.element = document.querySelector('.spinner');
|
||||
this.hide();
|
||||
}
|
||||
|
||||
show() {
|
||||
this.element.style.display = 'block';
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.element.style.display = 'none';
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
53
src/payform/payform.js
Normal file
53
src/payform/payform.js
Normal file
@ -0,0 +1,53 @@
|
||||
import 'whatwg-fetch';
|
||||
import Initialization from './backend-communication/Initialization';
|
||||
import EventPoller from './backend-communication/EventPoller';
|
||||
import Form from './elements/Form';
|
||||
import Spinner from './elements/Spinner';
|
||||
import Checkmark from './elements/Checkmark';
|
||||
import RequestBuilder from './builders/RequestBuilder';
|
||||
import settings from '../settings';
|
||||
import domReady from '../utils/domReady';
|
||||
|
||||
domReady(function () {
|
||||
let params = {};
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event && typeof event.data === 'object') {
|
||||
params = event.data
|
||||
}
|
||||
}, false);
|
||||
window.payformClose = () => window.parent.postMessage('payform-close', '*');
|
||||
|
||||
const spinner = new Spinner();
|
||||
const form = new Form();
|
||||
const checkmark = new Checkmark();
|
||||
|
||||
const handler = paymentTools => {
|
||||
const initRequest = RequestBuilder.buildInitRequest(params.invoiceId, paymentTools, form.getEmail());
|
||||
Initialization.sendInit(params.endpointInit, initRequest).then(() => {
|
||||
EventPoller.pollEvents(params.endpointEvents, params.invoiceId, settings.pollingTimeout).then(() => {
|
||||
spinner.hide();
|
||||
checkmark.show();
|
||||
setTimeout(() => window.parent.postMessage('payform-close', '*'), settings.closeFormTimeout);
|
||||
}).catch(() => {
|
||||
console.log('Error');
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
window.pay = () => {
|
||||
// const isValid = form.validate();
|
||||
spinner.show();
|
||||
form.hide();
|
||||
window.Tokenizer.setPublicKey(params.key);
|
||||
const request = RequestBuilder.buildTokenizationRequest(
|
||||
form.getCardHolder(),
|
||||
form.getCardNumber(),
|
||||
form.getExpDate(),
|
||||
form.getCvv()
|
||||
);
|
||||
window.Tokenizer.card.createToken(request, handler, error => {
|
||||
console.error(error)
|
||||
});
|
||||
};
|
||||
});
|
@ -5,6 +5,10 @@ html(lang='en')
|
||||
meta(http-equiv='X-UA-Compatible', content='IE=edge')
|
||||
meta(name='viewport', content='user-scalable=no,width=device-width,initial-scale=1,maximum-scale=1')
|
||||
title Payform
|
||||
script(src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.3/jquery.min.js")
|
||||
script(src="payment/payment.js")
|
||||
script(src="payform.js")
|
||||
script(src="http://localhost:7000/tokenizer.min.js")
|
||||
link(href='payform.css', rel='stylesheet')
|
||||
body
|
||||
.modal
|
||||
@ -28,42 +32,61 @@ html(lang='en')
|
||||
path(fill-rule='evenodd', transform='translate(9, 9)', d='M8.8,4 C8.8,1.79086089 7.76640339,4.18628304e-07 5.5,0 C3.23359661,-4.1480896e-07 2.2,1.79086089 2.2,4 L3.2,4 C3.2,2.34314567 3.81102123,0.999999681 5.5,1 C7.18897877,1.00000032 7.80000001,2.34314567 7.80000001,4 L8.8,4 Z M1.99201702,4 C0.891856397,4 0,4.88670635 0,5.99810135 L0,10.0018986 C0,11.1054196 0.900176167,12 1.99201702,12 L9.00798298,12 C10.1081436,12 11,11.1132936 11,10.0018986 L11,5.99810135 C11,4.89458045 10.0998238,4 9.00798298,4 L1.99201702,4 Z M1.99754465,5 C1.44661595,5 1,5.45097518 1,5.99077797 L1,10.009222 C1,10.5564136 1.4463114,11 1.99754465,11 L9.00245535,11 C9.55338405,11 10,10.5490248 10,10.009222 L10,5.99077797 C10,5.44358641 9.5536886,5 9.00245535,5 L1.99754465,5 Z M1.99754465,5')
|
||||
.modal--overlay
|
||||
.modal--container
|
||||
.modal--close
|
||||
.modal--close(onclick="payformClose()")
|
||||
.modal--body
|
||||
.payform
|
||||
.payform--header
|
||||
.payform--logo
|
||||
.payform--logo-image(style="background-image: url('logo.png')")
|
||||
.payform--logo-image(style="background-image: url('images/logo.png')")
|
||||
.payform--company-name Company name
|
||||
.payform--description Widget
|
||||
.payform--form
|
||||
form#payform(role='form')
|
||||
fieldset.payform--fieldset(style='display: none')
|
||||
.payform--email.payform--field__error
|
||||
input(type='email', value='', placeholder='Email', autocomplete='email', autocorrect='no', autocapitalize='no', spellcheck='no')
|
||||
.payform--icon
|
||||
svg(fill='#549928')
|
||||
use(xmlns:xlink='http://www.w3.org/1999/xlink', xlink:href='#Icon-envelope-desktop')
|
||||
fieldset.payform--fieldset
|
||||
.payform--card-holder.payform--field__error
|
||||
input(type='text', value='', placeholder='Card holder', autocomplete='off', autocorrect='no', autocapitalize='no', spellcheck='no')
|
||||
.payform--group.payform--card-holder
|
||||
input#card-holder(type='text', value='', placeholder='Card holder', autocomplete='off', autocorrect='no', autocapitalize='no', spellcheck='no')
|
||||
.payform--icon
|
||||
svg(fill='#549928')
|
||||
use(xmlns:xlink='http://www.w3.org/1999/xlink', xlink:href='#Icon-user-desktop')
|
||||
fieldset.payform--fieldset
|
||||
.payform--card-number.payform--field__error
|
||||
input(type='tel', value='', placeholder='Card number', autocomplete='off', autocorrect='no', autocapitalize='no', spellcheck='no')
|
||||
//.payform--card-number.payform--field__error.payform--field__focus
|
||||
.payform--group.payform--card-number
|
||||
input#card-number(type='tel', value='', placeholder='Card number', autocomplete='off', autocorrect='no', autocapitalize='no', spellcheck='no')
|
||||
.payform--icon
|
||||
svg(fill='#549928')
|
||||
use(xmlns:xlink='http://www.w3.org/1999/xlink', xlink:href='#Icon-creditCard-desktop')
|
||||
.payform--card-expire.payform--field__error.payform--field__focus
|
||||
input(type='tel', value='', placeholder='MM / YY', autocomplete='off', autocorrect='no', autocapitalize='no', spellcheck='no')
|
||||
.payform--group.payform--card-expire
|
||||
input#exp-date(type='tel', value='', placeholder='MM / YY', autocomplete='off', autocorrect='no', autocapitalize='no', spellcheck='no')
|
||||
.payform--icon
|
||||
svg(fill='#549928')
|
||||
use(xmlns:xlink='http://www.w3.org/1999/xlink', xlink:href='#Icon-calendar-desktop')
|
||||
.payform--card-cvc.payform--field__error
|
||||
input(type='tel', value='', placeholder='CVC', autocomplete='off', autocorrect='no', autocapitalize='no', spellcheck='no', maxlength='4')
|
||||
.payform--group.payform--card-cvc
|
||||
input#cvv(type='tel', value='', placeholder='CVC', autocomplete='off', autocorrect='no', autocapitalize='no', spellcheck='no', maxlength='4')
|
||||
.payform--icon
|
||||
svg(fill='#549928')
|
||||
use(xmlns:xlink='http://www.w3.org/1999/xlink', xlink:href='#Icon-lock-desktop')
|
||||
button.payform--pay-button(type='submit', form='payform') Pay $9.99
|
||||
fieldset.payform--fieldset
|
||||
.payform--group.payform--email
|
||||
input#email(type='email', value='', placeholder='Email', autocomplete='email', autocorrect='no', autocapitalize='no', spellcheck='no')
|
||||
.payform--icon
|
||||
svg(fill='#549928')
|
||||
use(xmlns:xlink='http://www.w3.org/1999/xlink', xlink:href='#Icon-envelope-desktop')
|
||||
button.payform--pay-button(type='button', form='payform', onclick="pay()") Pay
|
||||
div.spinner(style='transform:scale(0.54);')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(0deg) translate(0,-60px);transform:rotate(0deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(30deg) translate(0,-60px);transform:rotate(30deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(60deg) translate(0,-60px);transform:rotate(60deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(90deg) translate(0,-60px);transform:rotate(90deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(120deg) translate(0,-60px);transform:rotate(120deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(150deg) translate(0,-60px);transform:rotate(150deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(180deg) translate(0,-60px);transform:rotate(180deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(210deg) translate(0,-60px);transform:rotate(210deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(240deg) translate(0,-60px);transform:rotate(240deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(270deg) translate(0,-60px);transform:rotate(270deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(300deg) translate(0,-60px);transform:rotate(300deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div(style='top:80px;left:93px;width:14px;height:40px;background:#00b2ff;-webkit-transform:rotate(330deg) translate(0,-60px);transform:rotate(330deg) translate(0,-60px);border-radius:10px;position:absolute;')
|
||||
div.checkmark.icon.icon--order-success.svg
|
||||
svg(xmlns="http://www.w3.org/2000/svg" width="72px" height="72px")
|
||||
g(fill="none" stroke="#8EC343" stroke-width="2")
|
||||
circle(cx="36" cy="36" r="35" style="stroke-dasharray:240px, 240px; stroke-dashoffset: 480px;")
|
||||
path(d="M17.417,37.778l9.93,9.909l25.444-25.393" style="stroke-dasharray:50px, 50px; stroke-dashoffset: 0px;")
|
||||
|
652
src/payform/payment/payment.js
Normal file
652
src/payform/payment/payment.js
Normal file
@ -0,0 +1,652 @@
|
||||
(function() {
|
||||
var $, cardFromNumber, cardFromType, cards, defaultFormat, formatBackCardNumber, formatBackExpiry, formatCardNumber, formatExpiry, formatForwardExpiry, formatForwardSlashAndSpace, hasTextSelected, luhnCheck, reFormatCVC, reFormatCardNumber, reFormatExpiry, reFormatNumeric, replaceFullWidthChars, restrictCVC, restrictCardNumber, restrictExpiry, restrictNumeric, safeVal, setCardType,
|
||||
__slice = [].slice,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
$ = window.jQuery || window.Zepto || window.$;
|
||||
|
||||
$.payment = {};
|
||||
|
||||
$.payment.fn = {};
|
||||
|
||||
$.fn.payment = function() {
|
||||
var args, method;
|
||||
method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
||||
return $.payment.fn[method].apply(this, args);
|
||||
};
|
||||
|
||||
defaultFormat = /(\d{1,4})/g;
|
||||
|
||||
$.payment.cards = cards = [
|
||||
{
|
||||
type: 'maestro',
|
||||
patterns: [5018, 502, 503, 506, 56, 58, 639, 6220, 67],
|
||||
format: defaultFormat,
|
||||
length: [12, 13, 14, 15, 16, 17, 18, 19],
|
||||
cvcLength: [3],
|
||||
luhn: true
|
||||
}, {
|
||||
type: 'forbrugsforeningen',
|
||||
patterns: [600],
|
||||
format: defaultFormat,
|
||||
length: [16],
|
||||
cvcLength: [3],
|
||||
luhn: true
|
||||
}, {
|
||||
type: 'dankort',
|
||||
patterns: [5019],
|
||||
format: defaultFormat,
|
||||
length: [16],
|
||||
cvcLength: [3],
|
||||
luhn: true
|
||||
}, {
|
||||
type: 'visa',
|
||||
patterns: [4],
|
||||
format: defaultFormat,
|
||||
length: [13, 16],
|
||||
cvcLength: [3],
|
||||
luhn: true
|
||||
}, {
|
||||
type: 'mastercard',
|
||||
patterns: [51, 52, 53, 54, 55, 22, 23, 24, 25, 26, 27],
|
||||
format: defaultFormat,
|
||||
length: [16],
|
||||
cvcLength: [3],
|
||||
luhn: true
|
||||
}, {
|
||||
type: 'amex',
|
||||
patterns: [34, 37],
|
||||
format: /(\d{1,4})(\d{1,6})?(\d{1,5})?/,
|
||||
length: [15],
|
||||
cvcLength: [3, 4],
|
||||
luhn: true
|
||||
}, {
|
||||
type: 'dinersclub',
|
||||
patterns: [30, 36, 38, 39],
|
||||
format: /(\d{1,4})(\d{1,6})?(\d{1,4})?/,
|
||||
length: [14],
|
||||
cvcLength: [3],
|
||||
luhn: true
|
||||
}, {
|
||||
type: 'discover',
|
||||
patterns: [60, 64, 65, 622],
|
||||
format: defaultFormat,
|
||||
length: [16],
|
||||
cvcLength: [3],
|
||||
luhn: true
|
||||
}, {
|
||||
type: 'unionpay',
|
||||
patterns: [62, 88],
|
||||
format: defaultFormat,
|
||||
length: [16, 17, 18, 19],
|
||||
cvcLength: [3],
|
||||
luhn: false
|
||||
}, {
|
||||
type: 'jcb',
|
||||
patterns: [35],
|
||||
format: defaultFormat,
|
||||
length: [16],
|
||||
cvcLength: [3],
|
||||
luhn: true
|
||||
}
|
||||
];
|
||||
|
||||
cardFromNumber = function(num) {
|
||||
var card, p, pattern, _i, _j, _len, _len1, _ref;
|
||||
num = (num + '').replace(/\D/g, '');
|
||||
for (_i = 0, _len = cards.length; _i < _len; _i++) {
|
||||
card = cards[_i];
|
||||
_ref = card.patterns;
|
||||
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
|
||||
pattern = _ref[_j];
|
||||
p = pattern + '';
|
||||
if (num.substr(0, p.length) === p) {
|
||||
return card;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
cardFromType = function(type) {
|
||||
var card, _i, _len;
|
||||
for (_i = 0, _len = cards.length; _i < _len; _i++) {
|
||||
card = cards[_i];
|
||||
if (card.type === type) {
|
||||
return card;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
luhnCheck = function(num) {
|
||||
var digit, digits, odd, sum, _i, _len;
|
||||
odd = true;
|
||||
sum = 0;
|
||||
digits = (num + '').split('').reverse();
|
||||
for (_i = 0, _len = digits.length; _i < _len; _i++) {
|
||||
digit = digits[_i];
|
||||
digit = parseInt(digit, 10);
|
||||
if ((odd = !odd)) {
|
||||
digit *= 2;
|
||||
}
|
||||
if (digit > 9) {
|
||||
digit -= 9;
|
||||
}
|
||||
sum += digit;
|
||||
}
|
||||
return sum % 10 === 0;
|
||||
};
|
||||
|
||||
hasTextSelected = function($target) {
|
||||
var _ref;
|
||||
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== $target.prop('selectionEnd')) {
|
||||
return true;
|
||||
}
|
||||
if ((typeof document !== "undefined" && document !== null ? (_ref = document.selection) != null ? _ref.createRange : void 0 : void 0) != null) {
|
||||
if (document.selection.createRange().text) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
safeVal = function(value, $target) {
|
||||
var currPair, cursor, digit, error, last, prevPair;
|
||||
try {
|
||||
cursor = $target.prop('selectionStart');
|
||||
} catch (_error) {
|
||||
error = _error;
|
||||
cursor = null;
|
||||
}
|
||||
last = $target.val();
|
||||
$target.val(value);
|
||||
if (cursor !== null && $target.is(":focus")) {
|
||||
if (cursor === last.length) {
|
||||
cursor = value.length;
|
||||
}
|
||||
if (last !== value) {
|
||||
prevPair = last.slice(cursor - 1, +cursor + 1 || 9e9);
|
||||
currPair = value.slice(cursor - 1, +cursor + 1 || 9e9);
|
||||
digit = value[cursor];
|
||||
if (/\d/.test(digit) && prevPair === ("" + digit + " ") && currPair === (" " + digit)) {
|
||||
cursor = cursor + 1;
|
||||
}
|
||||
}
|
||||
$target.prop('selectionStart', cursor);
|
||||
return $target.prop('selectionEnd', cursor);
|
||||
}
|
||||
};
|
||||
|
||||
replaceFullWidthChars = function(str) {
|
||||
var chars, chr, fullWidth, halfWidth, idx, value, _i, _len;
|
||||
if (str == null) {
|
||||
str = '';
|
||||
}
|
||||
fullWidth = '\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19';
|
||||
halfWidth = '0123456789';
|
||||
value = '';
|
||||
chars = str.split('');
|
||||
for (_i = 0, _len = chars.length; _i < _len; _i++) {
|
||||
chr = chars[_i];
|
||||
idx = fullWidth.indexOf(chr);
|
||||
if (idx > -1) {
|
||||
chr = halfWidth[idx];
|
||||
}
|
||||
value += chr;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
reFormatNumeric = function(e) {
|
||||
var $target;
|
||||
$target = $(e.currentTarget);
|
||||
return setTimeout(function() {
|
||||
var value;
|
||||
value = $target.val();
|
||||
value = replaceFullWidthChars(value);
|
||||
value = value.replace(/\D/g, '');
|
||||
return safeVal(value, $target);
|
||||
});
|
||||
};
|
||||
|
||||
reFormatCardNumber = function(e) {
|
||||
var $target;
|
||||
$target = $(e.currentTarget);
|
||||
return setTimeout(function() {
|
||||
var value;
|
||||
value = $target.val();
|
||||
value = replaceFullWidthChars(value);
|
||||
value = $.payment.formatCardNumber(value);
|
||||
return safeVal(value, $target);
|
||||
});
|
||||
};
|
||||
|
||||
formatCardNumber = function(e) {
|
||||
var $target, card, digit, length, re, upperLength, value;
|
||||
digit = String.fromCharCode(e.which);
|
||||
if (!/^\d+$/.test(digit)) {
|
||||
return;
|
||||
}
|
||||
$target = $(e.currentTarget);
|
||||
value = $target.val();
|
||||
card = cardFromNumber(value + digit);
|
||||
length = (value.replace(/\D/g, '') + digit).length;
|
||||
upperLength = 16;
|
||||
if (card) {
|
||||
upperLength = card.length[card.length.length - 1];
|
||||
}
|
||||
if (length >= upperLength) {
|
||||
return;
|
||||
}
|
||||
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
|
||||
return;
|
||||
}
|
||||
if (card && card.type === 'amex') {
|
||||
re = /^(\d{4}|\d{4}\s\d{6})$/;
|
||||
} else {
|
||||
re = /(?:^|\s)(\d{4})$/;
|
||||
}
|
||||
if (re.test(value)) {
|
||||
e.preventDefault();
|
||||
return setTimeout(function() {
|
||||
return $target.val(value + ' ' + digit);
|
||||
});
|
||||
} else if (re.test(value + digit)) {
|
||||
e.preventDefault();
|
||||
return setTimeout(function() {
|
||||
return $target.val(value + digit + ' ');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
formatBackCardNumber = function(e) {
|
||||
var $target, value;
|
||||
$target = $(e.currentTarget);
|
||||
value = $target.val();
|
||||
if (e.which !== 8) {
|
||||
return;
|
||||
}
|
||||
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
|
||||
return;
|
||||
}
|
||||
if (/\d\s$/.test(value)) {
|
||||
e.preventDefault();
|
||||
return setTimeout(function() {
|
||||
return $target.val(value.replace(/\d\s$/, ''));
|
||||
});
|
||||
} else if (/\s\d?$/.test(value)) {
|
||||
e.preventDefault();
|
||||
return setTimeout(function() {
|
||||
return $target.val(value.replace(/\d$/, ''));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
reFormatExpiry = function(e) {
|
||||
var $target;
|
||||
$target = $(e.currentTarget);
|
||||
return setTimeout(function() {
|
||||
var value;
|
||||
value = $target.val();
|
||||
value = replaceFullWidthChars(value);
|
||||
value = $.payment.formatExpiry(value);
|
||||
return safeVal(value, $target);
|
||||
});
|
||||
};
|
||||
|
||||
formatExpiry = function(e) {
|
||||
var $target, digit, val;
|
||||
digit = String.fromCharCode(e.which);
|
||||
if (!/^\d+$/.test(digit)) {
|
||||
return;
|
||||
}
|
||||
$target = $(e.currentTarget);
|
||||
val = $target.val() + digit;
|
||||
if (/^\d$/.test(val) && (val !== '0' && val !== '1')) {
|
||||
e.preventDefault();
|
||||
return setTimeout(function() {
|
||||
return $target.val("0" + val + " / ");
|
||||
});
|
||||
} else if (/^\d\d$/.test(val)) {
|
||||
e.preventDefault();
|
||||
return setTimeout(function() {
|
||||
var m1, m2;
|
||||
m1 = parseInt(val[0], 10);
|
||||
m2 = parseInt(val[1], 10);
|
||||
if (m2 > 2 && m1 !== 0) {
|
||||
return $target.val("0" + m1 + " / " + m2);
|
||||
} else {
|
||||
return $target.val("" + val + " / ");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
formatForwardExpiry = function(e) {
|
||||
var $target, digit, val;
|
||||
digit = String.fromCharCode(e.which);
|
||||
if (!/^\d+$/.test(digit)) {
|
||||
return;
|
||||
}
|
||||
$target = $(e.currentTarget);
|
||||
val = $target.val();
|
||||
if (/^\d\d$/.test(val)) {
|
||||
return $target.val("" + val + " / ");
|
||||
}
|
||||
};
|
||||
|
||||
formatForwardSlashAndSpace = function(e) {
|
||||
var $target, val, which;
|
||||
which = String.fromCharCode(e.which);
|
||||
if (!(which === '/' || which === ' ')) {
|
||||
return;
|
||||
}
|
||||
$target = $(e.currentTarget);
|
||||
val = $target.val();
|
||||
if (/^\d$/.test(val) && val !== '0') {
|
||||
return $target.val("0" + val + " / ");
|
||||
}
|
||||
};
|
||||
|
||||
formatBackExpiry = function(e) {
|
||||
var $target, value;
|
||||
$target = $(e.currentTarget);
|
||||
value = $target.val();
|
||||
if (e.which !== 8) {
|
||||
return;
|
||||
}
|
||||
if (($target.prop('selectionStart') != null) && $target.prop('selectionStart') !== value.length) {
|
||||
return;
|
||||
}
|
||||
if (/\d\s\/\s$/.test(value)) {
|
||||
e.preventDefault();
|
||||
return setTimeout(function() {
|
||||
return $target.val(value.replace(/\d\s\/\s$/, ''));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
reFormatCVC = function(e) {
|
||||
var $target;
|
||||
$target = $(e.currentTarget);
|
||||
return setTimeout(function() {
|
||||
var value;
|
||||
value = $target.val();
|
||||
value = replaceFullWidthChars(value);
|
||||
value = value.replace(/\D/g, '').slice(0, 4);
|
||||
return safeVal(value, $target);
|
||||
});
|
||||
};
|
||||
|
||||
restrictNumeric = function(e) {
|
||||
var input;
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
return true;
|
||||
}
|
||||
if (e.which === 32) {
|
||||
return false;
|
||||
}
|
||||
if (e.which === 0) {
|
||||
return true;
|
||||
}
|
||||
if (e.which < 33) {
|
||||
return true;
|
||||
}
|
||||
input = String.fromCharCode(e.which);
|
||||
return !!/[\d\s]/.test(input);
|
||||
};
|
||||
|
||||
restrictCardNumber = function(e) {
|
||||
var $target, card, digit, value;
|
||||
$target = $(e.currentTarget);
|
||||
digit = String.fromCharCode(e.which);
|
||||
if (!/^\d+$/.test(digit)) {
|
||||
return;
|
||||
}
|
||||
if (hasTextSelected($target)) {
|
||||
return;
|
||||
}
|
||||
value = ($target.val() + digit).replace(/\D/g, '');
|
||||
card = cardFromNumber(value);
|
||||
if (card) {
|
||||
return value.length <= card.length[card.length.length - 1];
|
||||
} else {
|
||||
return value.length <= 16;
|
||||
}
|
||||
};
|
||||
|
||||
restrictExpiry = function(e) {
|
||||
var $target, digit, value;
|
||||
$target = $(e.currentTarget);
|
||||
digit = String.fromCharCode(e.which);
|
||||
if (!/^\d+$/.test(digit)) {
|
||||
return;
|
||||
}
|
||||
if (hasTextSelected($target)) {
|
||||
return;
|
||||
}
|
||||
value = $target.val() + digit;
|
||||
value = value.replace(/\D/g, '');
|
||||
if (value.length > 6) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
restrictCVC = function(e) {
|
||||
var $target, digit, val;
|
||||
$target = $(e.currentTarget);
|
||||
digit = String.fromCharCode(e.which);
|
||||
if (!/^\d+$/.test(digit)) {
|
||||
return;
|
||||
}
|
||||
if (hasTextSelected($target)) {
|
||||
return;
|
||||
}
|
||||
val = $target.val() + digit;
|
||||
return val.length <= 4;
|
||||
};
|
||||
|
||||
setCardType = function(e) {
|
||||
var $target, allTypes, card, cardType, val;
|
||||
$target = $(e.currentTarget);
|
||||
val = $target.val();
|
||||
cardType = $.payment.cardType(val) || 'unknown';
|
||||
if (!$target.hasClass(cardType)) {
|
||||
allTypes = (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = cards.length; _i < _len; _i++) {
|
||||
card = cards[_i];
|
||||
_results.push(card.type);
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
$target.removeClass('unknown');
|
||||
$target.removeClass(allTypes.join(' '));
|
||||
$target.addClass(cardType);
|
||||
$target.toggleClass('identified', cardType !== 'unknown');
|
||||
return $target.trigger('payment.cardType', cardType);
|
||||
}
|
||||
};
|
||||
|
||||
$.payment.fn.formatCardCVC = function() {
|
||||
this.on('keypress', restrictNumeric);
|
||||
this.on('keypress', restrictCVC);
|
||||
this.on('paste', reFormatCVC);
|
||||
this.on('change', reFormatCVC);
|
||||
this.on('input', reFormatCVC);
|
||||
return this;
|
||||
};
|
||||
|
||||
$.payment.fn.formatCardExpiry = function() {
|
||||
this.on('keypress', restrictNumeric);
|
||||
this.on('keypress', restrictExpiry);
|
||||
this.on('keypress', formatExpiry);
|
||||
this.on('keypress', formatForwardSlashAndSpace);
|
||||
this.on('keypress', formatForwardExpiry);
|
||||
this.on('keydown', formatBackExpiry);
|
||||
this.on('change', reFormatExpiry);
|
||||
this.on('input', reFormatExpiry);
|
||||
return this;
|
||||
};
|
||||
|
||||
$.payment.fn.formatCardNumber = function() {
|
||||
this.on('keypress', restrictNumeric);
|
||||
this.on('keypress', restrictCardNumber);
|
||||
this.on('keypress', formatCardNumber);
|
||||
this.on('keydown', formatBackCardNumber);
|
||||
this.on('keyup', setCardType);
|
||||
this.on('paste', reFormatCardNumber);
|
||||
this.on('change', reFormatCardNumber);
|
||||
this.on('input', reFormatCardNumber);
|
||||
this.on('input', setCardType);
|
||||
return this;
|
||||
};
|
||||
|
||||
$.payment.fn.restrictNumeric = function() {
|
||||
this.on('keypress', restrictNumeric);
|
||||
this.on('paste', reFormatNumeric);
|
||||
this.on('change', reFormatNumeric);
|
||||
this.on('input', reFormatNumeric);
|
||||
return this;
|
||||
};
|
||||
|
||||
$.payment.fn.cardExpiryVal = function() {
|
||||
return $.payment.cardExpiryVal($(this).val());
|
||||
};
|
||||
|
||||
$.payment.cardExpiryVal = function(value) {
|
||||
var month, prefix, year, _ref;
|
||||
_ref = value.split(/[\s\/]+/, 2), month = _ref[0], year = _ref[1];
|
||||
if ((year != null ? year.length : void 0) === 2 && /^\d+$/.test(year)) {
|
||||
prefix = (new Date).getFullYear();
|
||||
prefix = prefix.toString().slice(0, 2);
|
||||
year = prefix + year;
|
||||
}
|
||||
month = parseInt(month, 10);
|
||||
year = parseInt(year, 10);
|
||||
return {
|
||||
month: month,
|
||||
year: year
|
||||
};
|
||||
};
|
||||
|
||||
$.payment.validateCardNumber = function(num) {
|
||||
var card, _ref;
|
||||
num = (num + '').replace(/\s+|-/g, '');
|
||||
if (!/^\d+$/.test(num)) {
|
||||
return false;
|
||||
}
|
||||
card = cardFromNumber(num);
|
||||
if (!card) {
|
||||
return false;
|
||||
}
|
||||
return (_ref = num.length, __indexOf.call(card.length, _ref) >= 0) && (card.luhn === false || luhnCheck(num));
|
||||
};
|
||||
|
||||
$.payment.validateCardExpiry = function(month, year) {
|
||||
var currentTime, expiry, _ref;
|
||||
if (typeof month === 'object' && 'month' in month) {
|
||||
_ref = month, month = _ref.month, year = _ref.year;
|
||||
}
|
||||
if (!(month && year)) {
|
||||
return false;
|
||||
}
|
||||
month = $.trim(month);
|
||||
year = $.trim(year);
|
||||
if (!/^\d+$/.test(month)) {
|
||||
return false;
|
||||
}
|
||||
if (!/^\d+$/.test(year)) {
|
||||
return false;
|
||||
}
|
||||
if (!((1 <= month && month <= 12))) {
|
||||
return false;
|
||||
}
|
||||
if (year.length === 2) {
|
||||
if (year < 70) {
|
||||
year = "20" + year;
|
||||
} else {
|
||||
year = "19" + year;
|
||||
}
|
||||
}
|
||||
if (year.length !== 4) {
|
||||
return false;
|
||||
}
|
||||
expiry = new Date(year, month);
|
||||
currentTime = new Date;
|
||||
expiry.setMonth(expiry.getMonth() - 1);
|
||||
expiry.setMonth(expiry.getMonth() + 1, 1);
|
||||
return expiry > currentTime;
|
||||
};
|
||||
|
||||
$.payment.validateCardCVC = function(cvc, type) {
|
||||
var card, _ref;
|
||||
cvc = $.trim(cvc);
|
||||
if (!/^\d+$/.test(cvc)) {
|
||||
return false;
|
||||
}
|
||||
card = cardFromType(type);
|
||||
if (card != null) {
|
||||
return _ref = cvc.length, __indexOf.call(card.cvcLength, _ref) >= 0;
|
||||
} else {
|
||||
return cvc.length >= 3 && cvc.length <= 4;
|
||||
}
|
||||
};
|
||||
|
||||
$.payment.cardType = function(num) {
|
||||
var _ref;
|
||||
if (!num) {
|
||||
return null;
|
||||
}
|
||||
return ((_ref = cardFromNumber(num)) != null ? _ref.type : void 0) || null;
|
||||
};
|
||||
|
||||
$.payment.formatCardNumber = function(num) {
|
||||
var card, groups, upperLength, _ref;
|
||||
num = num.replace(/\D/g, '');
|
||||
card = cardFromNumber(num);
|
||||
if (!card) {
|
||||
return num;
|
||||
}
|
||||
upperLength = card.length[card.length.length - 1];
|
||||
num = num.slice(0, upperLength);
|
||||
if (card.format.global) {
|
||||
return (_ref = num.match(card.format)) != null ? _ref.join(' ') : void 0;
|
||||
} else {
|
||||
groups = card.format.exec(num);
|
||||
if (groups == null) {
|
||||
return;
|
||||
}
|
||||
groups.shift();
|
||||
groups = $.grep(groups, function(n) {
|
||||
return n;
|
||||
});
|
||||
return groups.join(' ');
|
||||
}
|
||||
};
|
||||
|
||||
$.payment.formatExpiry = function(expiry) {
|
||||
var mon, parts, sep, year;
|
||||
parts = expiry.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/);
|
||||
if (!parts) {
|
||||
return '';
|
||||
}
|
||||
mon = parts[1] || '';
|
||||
sep = parts[2] || '';
|
||||
year = parts[3] || '';
|
||||
if (year.length > 0) {
|
||||
sep = ' / ';
|
||||
} else if (sep === ' /') {
|
||||
mon = mon.substring(0, 1);
|
||||
sep = '';
|
||||
} else if (mon.length === 2 || sep.length > 0) {
|
||||
sep = ' / ';
|
||||
} else if (mon.length === 1 && (mon !== '0' && mon !== '1')) {
|
||||
mon = "0" + mon;
|
||||
sep = ' / ';
|
||||
}
|
||||
return mon + sep + year;
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
|
90
src/payform/styles/checkmark.css
Normal file
90
src/payform/styles/checkmark.css
Normal file
@ -0,0 +1,90 @@
|
||||
.checkmark {
|
||||
margin-left: 78px;
|
||||
margin-top: 57px;
|
||||
margin-bottom: 66px;
|
||||
}
|
||||
|
||||
/* animations */
|
||||
|
||||
@-webkit-keyframes checkmark {
|
||||
0% {
|
||||
stroke-dashoffset: 50px
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dashoffset: 0
|
||||
}
|
||||
}
|
||||
|
||||
@-ms-keyframes checkmark {
|
||||
0% {
|
||||
stroke-dashoffset: 50px
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dashoffset: 0
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes checkmark {
|
||||
0% {
|
||||
stroke-dashoffset: 50px
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dashoffset: 0
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes checkmark-circle {
|
||||
0% {
|
||||
stroke-dashoffset: 240px
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dashoffset: 480px
|
||||
}
|
||||
}
|
||||
|
||||
@-ms-keyframes checkmark-circle {
|
||||
0% {
|
||||
stroke-dashoffset: 240px
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dashoffset: 480px
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes checkmark-circle {
|
||||
0% {
|
||||
stroke-dashoffset: 240px
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dashoffset: 480px
|
||||
}
|
||||
}
|
||||
|
||||
/* other styles */
|
||||
/* .svg svg {
|
||||
display: none
|
||||
}
|
||||
*/
|
||||
.inlinesvg .svg svg {
|
||||
display: inline
|
||||
}
|
||||
|
||||
/* .svg img {
|
||||
display: none
|
||||
} */
|
||||
|
||||
.icon--order-success svg path {
|
||||
-webkit-animation: checkmark 0.25s ease-in-out 0.7s backwards;
|
||||
animation: checkmark 0.25s ease-in-out 0.7s backwards
|
||||
}
|
||||
|
||||
.icon--order-success svg circle {
|
||||
-webkit-animation: checkmark-circle 0.6s ease-in-out backwards;
|
||||
animation: checkmark-circle 0.6s ease-in-out backwards
|
||||
}
|
186
src/payform/styles/spinner.css
Normal file
186
src/payform/styles/spinner.css
Normal file
@ -0,0 +1,186 @@
|
||||
@-webkit-keyframes uil-default-anim {
|
||||
0% {
|
||||
opacity: 1
|
||||
}
|
||||
100% {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes uil-default-anim {
|
||||
0% {
|
||||
opacity: 1
|
||||
}
|
||||
100% {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(1) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: -0.5s;
|
||||
animation-delay: -0.5s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
margin-left: 17px;
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(2) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: -0.4166666666666667s;
|
||||
animation-delay: -0.4166666666666667s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(3) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: -0.33333333333333337s;
|
||||
animation-delay: -0.33333333333333337s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(4) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: -0.25s;
|
||||
animation-delay: -0.25s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(5) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: -0.16666666666666669s;
|
||||
animation-delay: -0.16666666666666669s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(6) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: -0.08333333333333331s;
|
||||
animation-delay: -0.08333333333333331s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(7) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: 0s;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(8) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: 0.08333333333333337s;
|
||||
animation-delay: 0.08333333333333337s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(9) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: 0.16666666666666663s;
|
||||
animation-delay: 0.16666666666666663s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(10) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: 0.25s;
|
||||
animation-delay: 0.25s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(11) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: 0.33333333333333337s;
|
||||
animation-delay: 0.33333333333333337s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.spinner > div:nth-of-type(12) {
|
||||
-webkit-animation: uil-default-anim 1s linear infinite;
|
||||
animation: uil-default-anim 1s linear infinite;
|
||||
-webkit-animation-delay: 0.41666666666666663s;
|
||||
animation-delay: 0.41666666666666663s;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
position: relative;
|
||||
background: none;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
40
src/payframe/elements/Iframe.js
Normal file
40
src/payframe/elements/Iframe.js
Normal file
@ -0,0 +1,40 @@
|
||||
export default class Iframe {
|
||||
constructor(src, name) {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('src', src);
|
||||
iframe.setAttribute('name', name);
|
||||
iframe.style.zIndex = '9999';
|
||||
iframe.style.overflowX = 'hidden';
|
||||
iframe.style.overflowY = 'auto';
|
||||
iframe.style.visibility = 'hidden';
|
||||
iframe.style.border = '0';
|
||||
iframe.style.display = 'none';
|
||||
iframe.style.background = `rgba(${0},${0},${0},${0.00392157})`;
|
||||
iframe.style.margin = '0px';
|
||||
iframe.style.padding = '0px';
|
||||
iframe.style.position = 'fixed';
|
||||
iframe.style.left = '0px';
|
||||
iframe.style.top = '0px';
|
||||
iframe.style.width = '100%';
|
||||
iframe.style.height = '100%';
|
||||
this.element = iframe;
|
||||
}
|
||||
|
||||
render() {
|
||||
document.body.appendChild(this.element);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
document.body.removeChild(this.element);
|
||||
}
|
||||
|
||||
show() {
|
||||
this.element.style.display = 'block';
|
||||
this.element.style.visibility = 'visible';
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.element.style.display = 'none';
|
||||
this.element.style.visibility = 'hidden';
|
||||
}
|
||||
}
|
19
src/payframe/elements/InitScript.js
Normal file
19
src/payframe/elements/InitScript.js
Normal file
@ -0,0 +1,19 @@
|
||||
export default class InitScript {
|
||||
constructor(className) {
|
||||
this.element = document.querySelector(`.${className}`);
|
||||
if (!this.element) {
|
||||
this.element = {};
|
||||
console.error(`Init script tag must contain ${className} class`);
|
||||
}
|
||||
}
|
||||
|
||||
getParams() {
|
||||
const dataSet = this.element.dataset;
|
||||
return {
|
||||
key: dataSet.key || {},
|
||||
invoiceId: dataSet.invoiceId || {},
|
||||
endpointInit: dataSet.endpointInit || {},
|
||||
endpointEvents: dataSet.endpointEvents || {}
|
||||
}
|
||||
}
|
||||
}
|
14
src/payframe/elements/PayButton.js
Normal file
14
src/payframe/elements/PayButton.js
Normal file
@ -0,0 +1,14 @@
|
||||
export default class PayButton {
|
||||
constructor(text) {
|
||||
const span = document.createElement('span');
|
||||
span.innerHTML = text;
|
||||
const button = document.createElement('button');
|
||||
button.className = 'rbkmoney-button';
|
||||
button.appendChild(span);
|
||||
this.element = button;
|
||||
}
|
||||
|
||||
render() {
|
||||
document.body.appendChild(this.element);
|
||||
}
|
||||
}
|
13
src/payframe/elements/StyleLink.js
Normal file
13
src/payframe/elements/StyleLink.js
Normal file
@ -0,0 +1,13 @@
|
||||
export default class StyleLink {
|
||||
constructor(href) {
|
||||
const link = document.createElement('link');
|
||||
link.setAttribute('rel', 'stylesheet');
|
||||
link.setAttribute('type', 'text/css');
|
||||
link.setAttribute('href', href);
|
||||
this.element = link;
|
||||
}
|
||||
|
||||
render() {
|
||||
document.getElementsByTagName('head')[0].appendChild(this.element);
|
||||
}
|
||||
}
|
112
src/payframe/payframe.css
Normal file
112
src/payframe/payframe.css
Normal file
@ -0,0 +1,112 @@
|
||||
.rbkmoney-button {
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
visibility: visible !important;
|
||||
background-image: -webkit-linear-gradient(#28a0e5, #015e94);
|
||||
background-image: -moz-linear-gradient(#28a0e5, #015e94);
|
||||
background-image: -ms-linear-gradient(#28a0e5, #015e94);
|
||||
background-image: -o-linear-gradient(#28a0e5, #015e94);
|
||||
background-image: -webkit-linear-gradient(#28a0e5, #015e94);
|
||||
background-image: -moz-linear-gradient(#28a0e5, #015e94);
|
||||
background-image: -ms-linear-gradient(#28a0e5, #015e94);
|
||||
background-image: -o-linear-gradient(#28a0e5, #015e94);
|
||||
background-image: linear-gradient(#28a0e5, #015e94);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
border: 0;
|
||||
padding: 1px;
|
||||
text-decoration: none;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-o-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
-webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
|
||||
-ms-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
|
||||
-o-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
cursor: pointer
|
||||
}
|
||||
|
||||
.rbkmoney-button::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0
|
||||
}
|
||||
|
||||
.rbkmoney-button span {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 0 12px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
background: #1275ff;
|
||||
background-image: -webkit-linear-gradient(#7dc5ee, #008cdd 85%, #30a2e4);
|
||||
background-image: -moz-linear-gradient(#7dc5ee, #008cdd 85%, #30a2e4);
|
||||
background-image: -ms-linear-gradient(#7dc5ee, #008cdd 85%, #30a2e4);
|
||||
background-image: -o-linear-gradient(#7dc5ee, #008cdd 85%, #30a2e4);
|
||||
background-image: -webkit-linear-gradient(#7dc5ee, #008cdd 85%, #30a2e4);
|
||||
background-image: -moz-linear-gradient(#7dc5ee, #008cdd 85%, #30a2e4);
|
||||
background-image: -ms-linear-gradient(#7dc5ee, #008cdd 85%, #30a2e4);
|
||||
background-image: -o-linear-gradient(#7dc5ee, #008cdd 85%, #30a2e4);
|
||||
background-image: linear-gradient(#7dc5ee, #008cdd 85%, #30a2e4);
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
|
||||
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
|
||||
-ms-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
|
||||
-o-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-ms-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
border-radius: 4px
|
||||
}
|
||||
|
||||
.rbkmoney-button:not(:disabled):active, .rbkmoney-button.active {
|
||||
background: #005d93
|
||||
}
|
||||
|
||||
.rbkmoney-button:not(:disabled):active span, .rbkmoney-button.active span {
|
||||
color: #eee;
|
||||
background: #008cdd;
|
||||
background-image: -webkit-linear-gradient(#008cdd, #008cdd 85%, #239adf);
|
||||
background-image: -moz-linear-gradient(#008cdd, #008cdd 85%, #239adf);
|
||||
background-image: -ms-linear-gradient(#008cdd, #008cdd 85%, #239adf);
|
||||
background-image: -o-linear-gradient(#008cdd, #008cdd 85%, #239adf);
|
||||
background-image: -webkit-linear-gradient(#008cdd, #008cdd 85%, #239adf);
|
||||
background-image: -moz-linear-gradient(#008cdd, #008cdd 85%, #239adf);
|
||||
background-image: -ms-linear-gradient(#008cdd, #008cdd 85%, #239adf);
|
||||
background-image: -o-linear-gradient(#008cdd, #008cdd 85%, #239adf);
|
||||
background-image: linear-gradient(#008cdd, #008cdd 85%, #239adf);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
|
||||
-ms-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
|
||||
-o-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.1)
|
||||
}
|
||||
|
||||
.rbkmoney-button:disabled, .rbkmoney-button.disabled {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
-ms-box-shadow: none;
|
||||
-o-box-shadow: none;
|
||||
box-shadow: none
|
||||
}
|
||||
|
||||
.rbkmoney-button:disabled span, .rbkmoney-button.disabled span {
|
||||
color: #999;
|
||||
background: #f8f9fa;
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5)
|
||||
}
|
33
src/payframe/payframe.js
Normal file
33
src/payframe/payframe.js
Normal file
@ -0,0 +1,33 @@
|
||||
import Iframe from './elements/Iframe';
|
||||
import PayButton from './elements/PayButton';
|
||||
import StyleLink from './elements/StyleLink';
|
||||
import InitScript from './elements/InitScript';
|
||||
import settings from '../settings';
|
||||
import domReady from '../utils/domReady';
|
||||
|
||||
domReady(function () {
|
||||
const frameUrl = `${settings.host}/payform/payform.html`;
|
||||
const frameName = 'rbkmoney_payframe';
|
||||
|
||||
const styles = new StyleLink(`${settings.host}/payframe/payframe.css`);
|
||||
const iframe = new Iframe(frameUrl, frameName);
|
||||
const payButton = new PayButton('Pay with RBKmoney');
|
||||
const initScript = new InitScript('rbkmoney-payform');
|
||||
|
||||
styles.render();
|
||||
payButton.render();
|
||||
iframe.render();
|
||||
|
||||
payButton.element.onclick = () => {
|
||||
iframe.show();
|
||||
window.frames[frameName].postMessage(initScript.getParams(), frameUrl);
|
||||
};
|
||||
|
||||
window.addEventListener('message', () => {
|
||||
if (event && event.data === 'payform-close') {
|
||||
iframe.hide();
|
||||
iframe.destroy();
|
||||
iframe.render();
|
||||
}
|
||||
}, false);
|
||||
});
|
6
src/settings.js
Normal file
6
src/settings.js
Normal file
@ -0,0 +1,6 @@
|
||||
export default {
|
||||
host: 'http://127.0.0.1:7050',
|
||||
pollingTimeout: 1000,
|
||||
closeFormTimeout: 2500
|
||||
// tokenizerUrl: 'http://127.0.0.1:7000'
|
||||
};
|
52
src/utils/domReady.js
Normal file
52
src/utils/domReady.js
Normal file
@ -0,0 +1,52 @@
|
||||
export default function (callback) {
|
||||
let ready = false;
|
||||
|
||||
const detach = function () {
|
||||
if (document.addEventListener) {
|
||||
document.removeEventListener('DOMContentLoaded', completed);
|
||||
window.removeEventListener('load', completed);
|
||||
} else {
|
||||
document.detachEvent('onreadystatechange', completed);
|
||||
window.detachEvent('onload', completed);
|
||||
}
|
||||
};
|
||||
const completed = function () {
|
||||
if (!ready && (document.addEventListener || event.type === 'load' || document.readyState === 'complete')) {
|
||||
ready = true;
|
||||
detach();
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
if (document.readyState === 'complete') {
|
||||
callback();
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('DOMContentLoaded', completed);
|
||||
window.addEventListener('load', completed);
|
||||
} else {
|
||||
document.attachEvent('onreadystatechange', completed);
|
||||
window.attachEvent('onload', completed);
|
||||
|
||||
let top = false;
|
||||
|
||||
try {
|
||||
top = window.frameElement == null && document.documentElement;
|
||||
} catch (e) {}
|
||||
|
||||
if (top && top.doScroll) {
|
||||
(function scrollCheck() {
|
||||
if (ready) return;
|
||||
|
||||
try {
|
||||
top.doScroll('left');
|
||||
} catch (e) {
|
||||
return setTimeout(scrollCheck, 50);
|
||||
}
|
||||
|
||||
ready = true;
|
||||
detach();
|
||||
callback();
|
||||
})();
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user