diff --git a/client/checkout/api/index.js b/client/checkout/api/index.js index fee6f6ad476..b5e5c3ac546 100644 --- a/client/checkout/api/index.js +++ b/client/checkout/api/index.js @@ -470,7 +470,6 @@ export default class WCPayAPI { return Promise.reject(); } - // TODO ~FR: send updated info to cart with cart token, and update accordingly. return window.wp.apiFetch( { method: 'POST', path: '/wc/store/v1/cart/update-customer', @@ -488,15 +487,21 @@ export default class WCPayAPI { * @param {Object} shippingOption Shipping option. * @return {Promise} Promise for the request to the server. */ - paymentRequestUpdateShippingDetails( shippingOption ) { - return this.request( - getPaymentRequestAjaxURL( 'update_shipping_method' ), - { - security: getPaymentRequestData( 'nonce' )?.update_shipping, - shipping_method: [ shippingOption.id ], - is_product_page: getPaymentRequestData( 'is_product_page' ), - } - ); + async paymentRequestUpdateShippingDetails( shippingOption ) { + if ( ! this.paymentRequestCartInfo ) { + return Promise.reject(); + } + + return window.wp.apiFetch( { + method: 'POST', + path: '/wc/store/v1/cart/select-shipping-rate', + headers: { + Nonce: this.paymentRequestCartInfo.nonce, + 'Cart-Token': this.paymentRequestCartInfo.cartToken, + }, + // TODO ~FR: send correct package id + data: { package_id: 0, rate_id: shippingOption.id }, + } ); } /** @@ -573,12 +578,46 @@ export default class WCPayAPI { // TODO ~FR: this is the juicy stuff return window.wp.apiFetch( { method: 'POST', - path: '/wc/store/v1/cart/add-item', + path: '/wc/store/v1/checkout', headers: { Nonce: this.paymentRequestCartInfo.nonce, 'Cart-Token': this.paymentRequestCartInfo.cartToken, }, - data: productData, + data: { + customer_note: paymentData.order_comments, + billing_address: { + first_name: paymentData.billing_first_name, + last_name: paymentData.billing_last_name, + // TODO ~FR + company: '', + address_1: paymentData.billing_address_1, + address_2: paymentData.billing_address_2, + city: paymentData.billing_city, + state: paymentData.billing_state, + postcode: paymentData.billing_postcode, + country: paymentData.billing_country, + email: paymentData.billing_email, + phone: paymentData.billing_phone, + }, + payment_method: 'woocommerce_payments', + payment_data: [ + { + // TODO ~FR + key: 'payment_request_type', + value: paymentData.payment_request_type, + }, + { + // TODO ~FR + key: 'wcpay-fraud-prevention-token', + value: paymentData[ 'wcpay-fraud-prevention-token' ], + }, + { + // TODO ~FR + key: 'wcpay-payment-method', + value: paymentData[ 'wcpay-payment-method' ], + }, + ], + }, } ); } diff --git a/client/payment-request/event-handlers.js b/client/payment-request/event-handlers.js index 7ff449a10d1..c56fb28490c 100644 --- a/client/payment-request/event-handlers.js +++ b/client/payment-request/event-handlers.js @@ -9,27 +9,45 @@ import { } from './utils'; export const shippingAddressChangeHandler = async ( api, event ) => { - // TODO ~FR: send updated info to cart with cart token, and update accordingly. const response = await api.paymentRequestCalculateShippingOptions( normalizeShippingAddress( event.shippingAddress ) ); // Possible statuses success, fail, invalid_payer_name, invalid_payer_email, invalid_payer_phone, invalid_shipping_address. event.updateWith( { + // TODO ~FR: correct status status: 'success', - // TODO ~FR: it shouldn't be a problem for product pages, but on cart pages with potentially multiple packages, things might get sketchy. + // TODO ~FR: it shouldn't be a problem for product pages, + // but on cart pages with potentially multiple packages, things might get sketchy. shippingOptions: response.shipping_rates[ 0 ].shipping_rates.map( ( rate ) => ( { id: rate.rate_id, label: rate.name, - amount: rate.price, + amount: parseInt( rate.price, 10 ), + detail: '', } ) ), - total: response.totals.total_price, - displayItems: response.items.map( ( item ) => ( { - label: item.name, - amount: item.prices.price, - } ) ), + total: { + label: '', // TODO ~FR, + amount: parseInt( response.totals.total_price, 10 ), + pending: false, + }, + displayItems: [ + ...response.items.map( ( item ) => ( { + label: item.name, + amount: parseInt( item.prices.price, 10 ), + } ) ), + { + // TODO ~FR, + label: 'Tax', + amount: parseInt( response.totals.total_tax, 10 ), + }, + { + // TODO ~FR, + label: 'Shipping', + amount: parseInt( response.totals.total_shipping, 10 ), + }, + ], } ); }; @@ -39,17 +57,31 @@ export const shippingOptionChangeHandler = async ( api, event ) => { event.shippingOption ); - if ( response.result === 'success' ) { - event.updateWith( { - status: 'success', - total: response.total, - displayItems: response.displayItems, - } ); - } - - if ( response.result === 'fail' ) { - event.updateWith( { status: 'fail' } ); - } + event.updateWith( { + // TODO ~FR: correct status + status: 'success', + total: { + label: '', // TODO ~FR, + amount: parseInt( response.totals.total_price, 10 ), + pending: false, + }, + displayItems: [ + ...response.items.map( ( item ) => ( { + label: item.name, + amount: parseInt( item.prices.price, 10 ), + } ) ), + { + // TODO ~FR, + label: 'Tax', + amount: parseInt( response.totals.total_tax, 10 ), + }, + { + // TODO ~FR, + label: 'Shipping', + amount: parseInt( response.totals.total_shipping, 10 ), + }, + ], + } ); }; const paymentResponseHandler = async ( @@ -59,21 +91,25 @@ const paymentResponseHandler = async ( abortPayment, event ) => { - if ( response.result !== 'success' ) { + if ( response.payment_result.payment_status !== 'success' ) { return abortPayment( event, + // TODO ~FR getErrorMessageFromNotice( response.messages ) ); } try { - const confirmationRequest = api.confirmIntent( response.redirect ); + const confirmationRequest = api.confirmIntent( + response.payment_result.redirect_url + ); // We need to call `complete` outside of `completePayment` to close the dialog for 3DS. event.complete( 'success' ); + // TODO ~FR: handle 3ds // `true` means there is no intent to confirm. if ( confirmationRequest === true ) { - completePayment( response.redirect ); + completePayment( response.payment_result.redirect_url ); } else { const redirectUrl = await confirmationRequest;