Skip to content

Commit

Permalink
Merge pull request #464 from rsolomakhin/gh-pages
Browse files Browse the repository at this point in the history
Web Payments API update.
  • Loading branch information
PaulKinlan committed Jan 18, 2017
2 parents 8f749df + c6f751d commit 74f5b89
Show file tree
Hide file tree
Showing 11 changed files with 541 additions and 188 deletions.
18 changes: 11 additions & 7 deletions paymentrequest/README.md
@@ -1,24 +1,28 @@
# PaymentRequest Recipes

- [Credit cards](https://googlechrome.github.io/samples/paymentrequest/credit-cards/index.html) -
- [Credit cards](https://googlechrome.github.io/samples/paymentrequest/credit-cards/) -
a sample that accepts credit card payments and does not request shipping
information.

- [Android Pay](https://googlechrome.github.io/samples/paymentrequest/android-pay/index.html) -
- [Android Pay](https://googlechrome.github.io/samples/paymentrequest/android-pay/) -
a sample that accepts Android Pay payments and does not request shipping
information.

- [Free shipping](https://googlechrome.github.io/samples/paymentrequest/free-shipping/index.html) -
- [Free shipping](https://googlechrome.github.io/samples/paymentrequest/free-shipping/) -
a sample that accepts credit card payments and provides free shipping worldwide.

- [Shipping options](https://googlechrome.github.io/samples/paymentrequest/shipping-options/index.html) -
- [Shipping options](https://googlechrome.github.io/samples/paymentrequest/shipping-options/) -
a sample that accepts credit card payments and provides a couple of shipping
options regardless of shipping address.

- [Dynamic shipping options](https://googlechrome.github.io/samples/paymentrequest/dynamic-shipping/index.html) -
- [Dynamic shipping options](https://googlechrome.github.io/samples/paymentrequest/dynamic-shipping/) -
a sample that accepts credit card payments and varies the availability and price
of shipping options depending on the shipping address.

- [Contact info](https://googlechrome.github.io/samples/paymentrequest/contact-info/index.html) -
- [Contact info](https://googlechrome.github.io/samples/paymentrequest/contact-info/) -
a sample that accepts credit card payments and requests user's contact
information: phone number and email address.
information: name, phone number, and email address.

- [Can make payment](https://googlechrome.github.io/samples/paymentrequest/can-make-payment/) -
a sample that accepts both Android Pay and credit card payments and checks
whether the browser can make payment.
84 changes: 50 additions & 34 deletions paymentrequest/android-pay/demo.js
@@ -1,10 +1,12 @@
/**
* Invokes PaymentRequest for Android Pay. If you encounter issues when running
* your own copy of this sample, run 'adb logcat | grep Wallet' to see detailed
* error messages.
* Builds PaymentRequest for Android Pay, but does not show any UI yet. If you
* encounter issues when running your own copy of this sample, run 'adb logcat |
* grep Wallet' to see detailed error messages.
*
* @return {PaymentRequest} The PaymentRequest object.
*/
function onBuyClicked() {
var supportedInstruments = [{
function initPaymentRequest() {
let supportedInstruments = [{
supportedMethods: ['https://android.com/pay'],
data: {
merchantName: 'Android Pay Demo',
Expand All @@ -21,34 +23,41 @@ function onBuyClicked() {
// Place your own Stripe publishable key here. Use a matching Stripe
// secret key on the server to initiate a transaction.
'stripe:publishableKey': 'pk_live_lNk21zqKM2BENZENh3rzCUgo',
'stripe:version': '2016-07-06'
}
}
}
'stripe:version': '2016-07-06',
},
},
},
}];

var details = {
let details = {
total: {label: 'Donation', amount: {currency: 'USD', value: '55.00'}},
displayItems: [
{
label: 'Original donation amount',
amount: {currency: 'USD', value: '65.00'}
amount: {currency: 'USD', value: '65.00'},
},
{
label: 'Friends and family discount',
amount: {currency: 'USD', value: '-10.00'}
}
]
amount: {currency: 'USD', value: '-10.00'},
},
],
};

new PaymentRequest(supportedInstruments, details) // eslint-disable-line no-undef
.show()
.then(function(instrumentResponse) {
sendPaymentToServer(instrumentResponse);
})
.catch(function(err) {
ChromeSamples.setStatus(err);
});
return new PaymentRequest(supportedInstruments, details);
}

/**
* Invokes PaymentRequest for Android Pay.
*
* @param {PaymentRequest} request The PaymentRequest object.
*/
function onBuyClicked(request) {
request.show().then(function(instrumentResponse) {
sendPaymentToServer(instrumentResponse);
})
.catch(function(err) {
ChromeSamples.setStatus(err);
});
}

/**
Expand All @@ -58,7 +67,7 @@ function onBuyClicked() {
* process.
*/
function sendPaymentToServer(instrumentResponse) {
// There's no server-side component of these samples. Not transactions are
// There's no server-side component of these samples. No transactions are
// processed and no money exchanged hands. Instantaneous transactions are not
// realistic. Add a 2 second delay to make it seem more real.
window.setTimeout(function() {
Expand All @@ -76,24 +85,31 @@ function sendPaymentToServer(instrumentResponse) {
/**
* Converts the payment instrument into a JSON string.
*
* @private
* @param {PaymentResponse} instrument The instrument to convert.
* @return {string} The JSON string representation of the instrument.
*/
function instrumentToJsonString(instrument) {
// PaymentInsrument is an interface, but JSON.stringify works only on
// dictionaries.
return JSON.stringify({
methodName: instrument.methodName,
details: instrument.details
}, undefined, 2);
if (instrument.toJSON) {
return JSON.stringify(instrument, undefined, 2);
} else {
return JSON.stringify({
methodName: instrument.methodName,
details: instrument.details,
}, undefined, 2);
}
}

var buyButton = document.getElementById('buyButton');
if ('PaymentRequest' in window) {
const buyButton = document.getElementById('buyButton');
buyButton.setAttribute('style', 'display: none;');
if (!navigator.userAgent.match(/Android/i)) {
ChromeSamples.setStatus('Supported only on Android for now.');
} else if ('PaymentRequest' in window) {
let request = initPaymentRequest();
buyButton.setAttribute('style', 'display: inline;');
buyButton.addEventListener('click', onBuyClicked);
buyButton.addEventListener('click', function() {
onBuyClicked(request);
request = initPaymentRequest();
});
} else {
buyButton.setAttribute('style', 'display: none;');
ChromeSamples.setStatus('This browser does not support web payments');
}
180 changes: 180 additions & 0 deletions paymentrequest/can-make-payment/demo.js
@@ -0,0 +1,180 @@
/**
* The callback for successful creation of PaymentRequest.
*
* @callback successCallback
* @param {PaymentRequest} request The newly created instance of PaymentRequest
* object.
* @param {string} optionalWarning The optional warning message to be used, for
* example, when unable to determine whether the browser can make payments.
*/

/**
* The callback for failed creation of PaymentRequest.
*
* @callback failureCallback
* @param {string} error The message indicating the reason why an instance of
* PaymentRequest was not created.
*/

/**
* Asynchronously builds PaymentRequest for both Android Pay and credit card
* payments, but does not show any UI yet. Succeeds only if can make payments.
* If you encounter issues when running your own copy of this sample, run 'adb
* logcat | grep Wallet' to see detailed error messages.
*
* @param {successCallback} onSuccess The callback to invoke when this function
* is finished successfully.
* @param {failureCallback} onFailure The callback to invoke when this function
* is finished with failure.
*/
function initPaymentRequest(onSuccess, onFailure) {
if (!navigator.userAgent.match(/Android/i)) {
onFailure('Supported only on Android for now.');
return;
}

if (!('PaymentRequest' in window)) {
onFailure('This browser does not support web payments.');
return;
}

let networks = ['amex', 'diners', 'discover', 'jcb', 'mastercard', 'unionpay',
'visa', 'mir'];
let types = ['debit', 'credit', 'prepaid'];
let supportedInstruments = [{
supportedMethods: ['https://android.com/pay'],
data: {
merchantName: 'Android Pay Demo',
// Place your own Android Pay merchant ID here. The merchant ID is tied to
// the origin of the website.
merchantId: '00184145120947117657',
// If you do not yet have a merchant ID, uncomment the following line.
// environment: 'TEST',
allowedCardNetworks: ['AMEX', 'DISCOVER', 'MASTERCARD', 'VISA'],
paymentMethodTokenizationParameters: {
tokenizationType: 'GATEWAY_TOKEN',
parameters: {
'gateway': 'stripe',
// Place your own Stripe publishable key here. Use a matching Stripe
// secret key on the server to initiate a transaction.
'stripe:publishableKey': 'pk_live_lNk21zqKM2BENZENh3rzCUgo',
'stripe:version': '2016-07-06',
},
},
},
}, {
supportedMethods: networks,
}, {
supportedMethods: ['basic-card'],
data: {supportedNetworks: networks, supportedTypes: types},
}];

let details = {
total: {label: 'Donation', amount: {currency: 'USD', value: '55.00'}},
displayItems: [
{
label: 'Original donation amount',
amount: {currency: 'USD', value: '65.00'},
},
{
label: 'Friends and family discount',
amount: {currency: 'USD', value: '-10.00'},
},
],
};

let request = new PaymentRequest(supportedInstruments, details);

if (request.canMakePayment) {
request.canMakePayment().then(function(result) {
if (result) {
onSuccess(request);
} else {
onFailure('Cannot make payment');
}
}).catch(function(err) {
onSuccess(request, err);
});
} else {
onSuccess(
request, 'This browser does not support "can make payment" query');
}
}

/**
* Invokes PaymentRequest for Android Pay.
*
* @param {PaymentRequest} request The PaymentRequest object.
*/
function onBuyClicked(request) {
request.show().then(function(instrumentResponse) {
sendPaymentToServer(instrumentResponse);
})
.catch(function(err) {
ChromeSamples.setStatus(err);
});
}

/**
* Simulates processing the payment data on the server.
*
* @param {PaymentResponse} instrumentResponse The payment information to
* process.
*/
function sendPaymentToServer(instrumentResponse) {
// There's no server-side component of these samples. No transactions are
// processed and no money exchanged hands. Instantaneous transactions are not
// realistic. Add a 2 second delay to make it seem more real.
window.setTimeout(function() {
instrumentResponse.complete('success')
.then(function() {
document.getElementById('result').innerHTML =
instrumentToJsonString(instrumentResponse);
})
.catch(function(err) {
ChromeSamples.setStatus(err);
});
}, 2000);
}

/**
* Converts the payment instrument into a JSON string.
*
* @param {PaymentResponse} instrument The instrument to convert.
* @return {string} The JSON string representation of the instrument.
*/
function instrumentToJsonString(instrument) {
if (instrument.toJSON) {
return JSON.stringify(instrument, undefined, 2);
} else {
return JSON.stringify({
methodName: instrument.methodName,
details: instrument.details,
}, undefined, 2);
}
}

/**
* Initializes the buy button.
*
* @param {HTMLElement} buyButton The "Buy" button to initialize.
*/
function initBuyButton(buyButton) {
initPaymentRequest(function(request, optionalWarning) {
buyButton.setAttribute('style', 'display: inline;');
ChromeSamples.setStatus(optionalWarning ? optionalWarning : '');
buyButton.addEventListener('click', function handleClick() {
buyButton.removeEventListener('click', handleClick);
onBuyClicked(request);
initBuyButton(buyButton);
});
}, function(error) {
buyButton.setAttribute('style', 'display: none;');
ChromeSamples.setStatus(error);
});
}

const buyButton = document.getElementById('buyButton');
buyButton.setAttribute('style', 'display: none;');
ChromeSamples.setStatus('Checking...');
initBuyButton(buyButton);
24 changes: 24 additions & 0 deletions paymentrequest/can-make-payment/index.html
@@ -0,0 +1,24 @@
---
feature_name: PaymentRequest Can Make Payment
chrome_version: 56
feature_id: 5639348045217792
---

<h3>Background</h3>
<p>
<a href="https://github.com/w3c/browser-payment-api">PaymentRequest</a> lets
you accept payment from different payment methods.
</p>

<p>
This sample accepts both Android Pay and credit card payments and checks
whether the browser can make payment.
</p>

{% capture initial_output_content %}
<div><button id="buyButton">Buy</button></div>
<div><pre id="result"></pre></div>
{% endcapture %}
{% include output_helper.html initial_output_content=initial_output_content %}

{% include js_snippet.html filename='demo.js' %}

0 comments on commit 74f5b89

Please sign in to comment.