Skip to content

Instantly share code, notes, and snippets.

@dtanphat9388
Last active May 5, 2018 11:48
Show Gist options
  • Save dtanphat9388/d7296f4ae6b282289e580a71e51e6ebd to your computer and use it in GitHub Desktop.
Save dtanphat9388/d7296f4ae6b282289e580a71e51e6ebd to your computer and use it in GitHub Desktop.
Payment Request API

diagram

  1. tạo payment request

    let paymentReq = new PaymentRequest([paymentMethod], details, options)
    • paymentMethod: app defined
    • details: popup for user select
    • options: app defined

    1.1 APP DEFINED
    - Shipping option
    - Payment method

  2. show payment UI cho user

    paymentReq.show():Promise<paymentResponse>
  3. xử lý các thay đổi trên payment UI

    paymentReq.onshippingoptionchange = (e:PaymentRequestUpdateEvent) => {
        e.responseWith(<paymentReqOptions>)
    }

    paymentReqOptions

    {
        displayItems[]: [],
        "error": "",
        modifiers: '',
        shippingOptions:'',
        total: .....    
    }
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button style="-webkit-appearance: -apple-pay-button;"></button>
<script>
let log = console.log
class paymentItem {
constructor(label, price, currency='USD') {
this.label = label
this.amount = { currency: currency, value: price }
this.pending = true
}
}
/**
* HELPER FUNCTION
*/
function getDisplayItems(products, currency="VND") {
return products.map( item => new paymentItem(item.name, item.price, currency) )
}
function getPriceOfProducts(products) {
return products.reduce((prev, cur) => prev.price + cur.price)
}
function getPriceOfShipping(shippingOptions) {
return shippingOptions.find( shipItem => shipItem.selected == true ).amount.value
}
function getTaxOfProducts(totalPriceOfProducts, tax=0.1) {
return totalPriceOfProducts * tax
}
function getTotalPrice(products, shipping, tax) {
let totalPrices = products + tax + shipping
return new paymentItem("TOTAL", totalPrices)
}
function showPaymentUI(paymentReq) {
paymentReq.show() // start trigger payment process
.then(paymentResponse => log('payment response: ', paymentResponse))
.catch(err => log('payment response cancelled: ', err.message)) // khi user cancel payment
}
/**
* SIMULATION DATA
*/
// user defined
let products = [
{
name: 'ao khoac',
price: 100
},
{
name: 'quan dai',
price: 65
}
]
// app defined
let discount = 3
/** --------------- MAIN --------------- */
try {
let shippingOptions = [
{
id: 'standard',
label: 'Standard shipping (2 ngày)',
amount: {
currency: 'USD',
value: 0 //free
},
selected: false // default select
},
{
id: 'express',
label: 'giao hang nhanh (trong ngày)',
amount: {
currency: 'USD',
value: 30
},
selected: true
}
]
let priceOfProducts = getPriceOfProducts(products)
let priceOfTax = getTaxOfProducts(priceOfProducts)
let priceOfShipping = getPriceOfShipping(shippingOptions)
let paymentReqMethod = {
supportedMethods: 'basic-card', // google pay, samsung pay.... tham khao cach setup
data: {
/** https://developer.mozilla.org/en-US/docs/Web/API/BasicCardRequest/supportedNetworks */
supportedNetworks: ['visa', 'jcb', 'mastercard'], //['visa' || 'mastercard' || 'amex' || 'jcb' || 'diners' || 'discover' || 'mir' || 'unionpay']
/** https://developer.mozilla.org/en-US/docs/Web/API/BasicCardRequest/supportedTypes */
supportedTypes: ['credit', 'debit'] // ['credit' || 'debit' || 'prepaid']
}
}
let paymentReqDetails = {
/**
* A free-form identifier for this payment request.
* If a value is not supplied, the browser will construct one.
*/
id: `dtanphat9388-${Date.now()}`, // id giao dich
/**
* An array of optional line items for the payment request that the user agent may display,
* such as product details, tax, and shipping.
*/
displayItems: getDisplayItems(products, 'USD'),
/**
* The shipping options the user may choose from.
* If this sequence is blank, it indicates the merchant cannot ship to the current shipping address
* must enable in options
*/
shippingOptions,
modifiers: [{
supportedMethods: 'basic-card',
data: {
supportedNetworks: ['visa', 'jcb', 'mastercard'],
supportedTypes: ['credit', 'debit']
},
additionalDisplayItems: [
new paymentItem('DISCOUNT', 3),
new paymentItem('TAX', 50)
],
total: new paymentItem('Credit card price', 71)
}],
/**
* The total amount of the payment request.
*/
total: getTotalPrice(priceOfProducts, priceOfShipping, priceOfTax)
};
let paymentReqOptions = {
requestPayerName: true,
requestPayerEmail: true,
requestPayerPhone: true,
requestShipping: true,
shippingType: 'delivery' // delivery | shipping | pickup
};
/**
* @paymentMethod: Contains an array of identifiers for the payment methods the merchant web site accepts and any associated payment method specific data
* @data: Provides information about the requested transaction
* @options: Lets you set options that control the behavior of the user agent
*/
let paymentReq = new PaymentRequest([paymentReqMethod], paymentReqDetails, paymentReqOptions)
paymentReq.canMakePayment()
.then( isSuccess => isSuccess && showPaymentUI(paymentReq) )
.catch( err => alert("co loi khi payment hoac chua du dieu kien") )
paymentReq.onshippingoptionchange = (e) => {
log(paymentReq)
e.updateWith(async function() {
let newShippingSelected = paymentReqDetails.shippingOptions.map( shipItem => {
shipItem.selected = shipItem.id == e.target.shippingOption
return shipItem
})
let priceOfShipping = getPriceOfShipping(newShippingSelected)
let newPaymentReqOptions = {
displayItems: getDisplayItems(products),
shippingOptions: newShippingSelected,
total: getTotalPrice(priceOfProducts, priceOfShipping, priceOfTax)
}
return newPaymentReqOptions
}())
}
paymentReq.onshippingaddresschange = (e) => {
log('shipping address change', e)
}
} catch (e) {
log(e.message)
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment