user-accepts-payment-request-algo-manual.https.html (7660B)
1 <!doctype html> 2 <meta charset="utf8"> 3 <link rel="help" href="https://w3c.github.io/payment-request/#user-accepts-the-payment-request-algorithm"> 4 <title> 5 User accepts the payment request algorithm 6 </title> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script> 10 setup({ explicit_done: true, explicit_timeout: true }); 11 const applePay = Object.freeze({ 12 supportedMethods: "https://apple.com/apple-pay", 13 data: { 14 version: 3, 15 merchantIdentifier: "merchant.com.example", 16 countryCode: "US", 17 merchantCapabilities: ["supports3DS"], 18 supportedNetworks: ["visa"], 19 } 20 }); 21 const basicCardMethod = Object.freeze({ 22 supportedMethods: "basic-card", 23 }); 24 const validMethod = Object.freeze({ 25 supportedMethods: "this-is-just-for-testings-will-never-match", 26 }); 27 const methods = Object.freeze([basicCardMethod, validMethod, applePay]); 28 const validAmount = Object.freeze({ 29 currency: "USD", 30 value: "5.00", 31 }); 32 const shippingOptions = [ 33 Object.freeze({ 34 id: "option1", 35 label: "Option 1", 36 amount: validAmount, 37 selected: false, 38 }), 39 Object.freeze({ 40 id: "option 2", 41 label: "Option 2", 42 amount: validAmount, 43 selected: true, 44 }), 45 ]; 46 47 const detailsNoShippingOptions = Object.freeze({ 48 total: { 49 label: "Total due", 50 amount: validAmount, 51 }, 52 }); 53 54 const detailsWithShippingOptions = Object.assign({}, detailsNoShippingOptions, { 55 shippingOptions, 56 }); 57 58 const optionsRequestNothing = Object.freeze({ 59 requestShipping: false, 60 requestPayerEmail: false, 61 requestPayerName: false, 62 requestPayerPhone: false, 63 }); 64 65 const optionsRequestEverything = Object.freeze({ 66 requestShipping: true, 67 requestPayerEmail: true, 68 requestPayerName: true, 69 requestPayerPhone: true, 70 }); 71 72 test(() => { 73 // smoke test 74 try { 75 new PaymentRequest(methods, detailsNoShippingOptions); 76 } catch (err) { 77 done(); 78 throw err; 79 } 80 }, "Must be able to construct a payment request (smoke test)"); 81 82 function testAcceptRequestAlgorithm( 83 button, 84 details, 85 options = {}, 86 expectedResponse = {} 87 ) { 88 button.disabled = true; 89 promise_test(async t => { 90 const request = new PaymentRequest(methods, details, options); 91 const response = await request.show(); 92 assert_true( 93 response instanceof PaymentResponse, 94 "Expected an instance of PaymentResponse." 95 ); 96 // Response [[calledComplete]] is false, so this shouldn't throw 97 await response.complete("success"); 98 // For good measure, test that subsequent complete() 99 for (const state of [undefined, "success", "fail", "unknown"]) { 100 await promise_rejects_dom( 101 t, 102 "InvalidStateError", 103 response.complete(state), 104 "Response [[calledComplete]] is true, so InvalidStateError" 105 ); 106 } 107 assert_equals( 108 request.id, 109 response.requestId, 110 "Request and response ids must match." 111 ); 112 assert_true(response.details instanceof Object, "Expected an object"); 113 assert_equals( 114 response.shippingAddress, 115 request.shippingAddress, 116 "Request and response must reference same shippingAddress (or both null)." 117 ); 118 assert_equals( 119 response.shippingOption, 120 request.shippingOption, 121 "Request and response must be the same value (or both null)." 122 ); 123 if (options.requestShipping === true) { 124 assert_true( 125 response.shippingAddress instanceof ContactAddress, 126 "Expected an instance of ContactAddress." 127 ); 128 } 129 const expected = { 130 methodName: "basic-card", 131 payerEmail: options.requestPayerEmail 132 ? expectedResponse.payerEmail 133 : null, 134 payerName: options.requestPayerName ? expectedResponse.payerName : null, 135 payerPhone: options.requestPayerPhone 136 ? expectedResponse.payerPhone 137 : null, 138 }; 139 for (const [attr, expectedValue] of Object.entries(expected)) { 140 assert_equals( 141 response[attr], 142 expectedValue, 143 `response.${attr} must be ${expectedValue}` 144 ); 145 } 146 await promise_rejects_dom( 147 t, 148 "InvalidStateError", 149 request.show(), 150 "Request [[state]] is closed, so InvalidStateError" 151 ); 152 }, button.textContent.trim()); 153 } 154 155 </script> 156 157 <section> 158 <h2 id="user-accepts-payment-request">User accepts payment request</h2> 159 <p> 160 Click on each button in sequence from top to bottom without refreshing the page. 161 Each button will bring up the Payment Request UI window. 162 </p> 163 <p> 164 When shown the payment sheet, please input a credit card and select Pay. 165 </p> 166 <ol> 167 <li> 168 <button onclick=" 169 const detailsWithId = Object.assign({}, detailsNoShippingOptions, { id: 'pass' }); 170 testAcceptRequestAlgorithm(this, detailsWithId, optionsRequestNothing);"> 171 User accepts payment request, but not shipping is requested. 172 </button> Use any credit card to pay. 173 </li> 174 <li> 175 <button onclick=" 176 const requestShipping = Object.assign({}, optionsRequestNothing, {requestShipping: true}); 177 const expectedValues = { shippingOption: 'option 2' }; 178 testAcceptRequestAlgorithm(this, detailsWithShippingOptions, requestShipping, expectedValues);"> 179 User accepts payment request, merchant requests shipping. 180 </button> Select any shipping option, and use any credit card to pay. 181 </li> 182 <li> 183 <button onclick=" 184 const requestPayerEmail = Object.assign({}, optionsRequestNothing, {requestPayerEmail: true}); 185 const expectValues = { payerEmail: 'wpt@w3.org' }; 186 testAcceptRequestAlgorithm(this, detailsNoShippingOptions, requestPayerEmail, expectValues);"> 187 User accepts payment request, merchant requests email. 188 </button> 189 When prompted, please use "wpt@w3.org" as the email. 190 </li> 191 <li> 192 <button onclick=" 193 const requestPayerPhone = Object.assign({}, optionsRequestNothing, {requestPayerPhone: true}); 194 const expectValues = { payerPhone: '+12345678910' }; 195 testAcceptRequestAlgorithm(this, detailsNoShippingOptions, requestPayerPhone, expectValues);"> 196 User accepts payment request, merchant requests phone. 197 </button> 198 When prompted, please use "+12345678910" as the phone number. 199 </li> 200 <li> 201 <button onclick=" 202 const requestPayerName = Object.assign({}, optionsRequestNothing, {requestPayerName: true}); 203 const expectValues = { payerName: 'web platform test' }; 204 testAcceptRequestAlgorithm(this, detailsNoShippingOptions, requestPayerName, expectValues);"> 205 User accepts payment request, merchant requests payer's name. 206 </button> 207 When prompted, please use "web platform test" as the payer name. 208 </li> 209 <li> 210 <button onclick=" 211 const expectValues = { 212 payerEmail: 'wpt@w3.org', 213 payerName: 'web platform test', 214 payerPhone: '+12345678910', 215 shippingOption: 'option 2', 216 }; 217 testAcceptRequestAlgorithm(this, detailsWithShippingOptions, optionsRequestEverything, expectValues);"> 218 User accepts payment request, merchant requests everything. 219 </button> 220 When prompted, please use: "+12345678910" as the phone number, "web platform test" as the payer name, and "wpt@w3.org" as the email. Then press Pay. 221 </li> 222 <li> 223 <button onclick="done()">Done</button> 224 </li> 225 </ol> 226 </section> 227 <small> 228 If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> 229 and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>. 230 </small>