1/** 2 * This PaypalExpressCheckout global is included by wp_enqueue_script( 'jetpack-paypal-express-checkout' ); 3 * It handles communication with Paypal Express checkout and public-api.wordpress.com for the purposes 4 * of simple-payments module. 5 */ 6 7/* global paypal */ 8/* exported PaypalExpressCheckout */ 9const PaypalExpressCheckout = { 10 primaryCssClassName: 'jetpack-simple-payments', 11 messageCssClassName: 'jetpack-simple-payments-purchase-message', 12 13 wpRestAPIHost: 'https://public-api.wordpress.com', 14 wpRestAPIVersion: '/wpcom/v2', 15 16 getEnvironment: function () { 17 if ( 18 localStorage && 19 localStorage.getItem && 20 localStorage.getItem( 'simple-payments-env' ) === 'sandbox' 21 ) { 22 return 'sandbox'; 23 } 24 return 'production'; 25 }, 26 27 getCreatePaymentEndpoint: function ( blogId ) { 28 return ( 29 PaypalExpressCheckout.wpRestAPIHost + 30 PaypalExpressCheckout.wpRestAPIVersion + 31 '/sites/' + 32 blogId + 33 '/simple-payments/paypal/payment' 34 ); 35 }, 36 37 getExecutePaymentEndpoint: function ( blogId, paymentId ) { 38 return ( 39 PaypalExpressCheckout.wpRestAPIHost + 40 PaypalExpressCheckout.wpRestAPIVersion + 41 '/sites/' + 42 blogId + 43 '/simple-payments/paypal/' + 44 paymentId + 45 '/execute' 46 ); 47 }, 48 49 getNumberOfItems: function ( field, enableMultiple ) { 50 if ( enableMultiple !== '1' ) { 51 return 1; 52 } 53 54 const numberField = document.getElementById( field ); 55 56 if ( ! numberField ) { 57 return 1; 58 } 59 60 const number = Number( numberField.value ); 61 62 if ( isNaN( number ) ) { 63 return 1; 64 } 65 return number; 66 }, 67 68 /** 69 * Get the DOM element-placeholder used to show message 70 * about the transaction. If it doesn't exist then the function will create a new one. 71 * 72 * @param {string} domId - domId id of the payment button placeholder 73 * @return {Element} the dom element to print the message 74 */ 75 getMessageContainer: function ( domId ) { 76 return document.getElementById( domId + '-message-container' ); 77 }, 78 79 /** 80 * Show a messange close to the Paypal button. 81 * Use this function to give feedback to the user according 82 * to the transaction result. 83 * 84 * @param {string} message - message to show 85 * @param {string} domId - paypal-button element dom identifier 86 * @param {boolean} [isError] - defines if it's a message error. Not TRUE as default. 87 */ 88 showMessage: function ( message, domId, isError ) { 89 const domEl = PaypalExpressCheckout.getMessageContainer( domId ); 90 91 // set css classes 92 let cssClasses = PaypalExpressCheckout.messageCssClassName + ' show '; 93 cssClasses += isError ? 'error' : 'success'; 94 95 // show message 1s after PayPal popup is closed 96 setTimeout( function () { 97 domEl.innerHTML = message; 98 domEl.setAttribute( 'class', cssClasses ); 99 }, 1000 ); 100 }, 101 102 showError: function ( message, domId ) { 103 PaypalExpressCheckout.showMessage( message, domId, true ); 104 }, 105 106 processErrorMessage: function ( errorResponse ) { 107 const error = errorResponse ? errorResponse.responseJSON : null; 108 const defaultMessage = 'There was an issue processing your payment.'; 109 110 if ( ! error ) { 111 return '<p>' + defaultMessage + '</p>'; 112 } 113 114 if ( error.additional_errors ) { 115 const messages = []; 116 error.additional_errors.forEach( function ( additionalError ) { 117 if ( additionalError.message ) { 118 messages.push( '<p>' + additionalError.message.toString() + '</p>' ); 119 } 120 } ); 121 return messages.join( '' ); 122 } 123 124 return '<p>' + ( error.message || defaultMessage ) + '</p>'; 125 }, 126 127 processSuccessMessage: function ( successResponse ) { 128 const message = successResponse.message; 129 const defaultMessage = 'Thank you. Your purchase was successful!'; 130 131 if ( ! message ) { 132 return '<p>' + defaultMessage + '</p>'; 133 } 134 135 return '<p>' + message + '</p>'; 136 }, 137 138 cleanAndHideMessage: function ( domId ) { 139 const domEl = PaypalExpressCheckout.getMessageContainer( domId ); 140 domEl.setAttribute( 'class', PaypalExpressCheckout.messageCssClassName ); 141 domEl.innerHTML = ''; 142 }, 143 144 renderButton: function ( blogId, buttonId, domId, enableMultiple ) { 145 const env = PaypalExpressCheckout.getEnvironment(); 146 147 if ( ! paypal ) { 148 throw new Error( 'PayPal module is required by PaypalExpressCheckout' ); 149 } 150 151 const buttonDomId = domId + '_button'; 152 153 paypal.Button.render( 154 { 155 env: env, 156 commit: true, 157 158 style: { 159 label: 'pay', 160 shape: 'rect', 161 color: 'silver', 162 size: 'responsive', 163 fundingicons: true, 164 }, 165 166 payment: function () { 167 PaypalExpressCheckout.cleanAndHideMessage( domId ); 168 169 const payload = { 170 number: PaypalExpressCheckout.getNumberOfItems( domId + '_number', enableMultiple ),
171 buttonId: buttonId, 172 env: env, 173 }; 174 175 return new paypal.Promise( function ( resolve, reject ) { 176 // eslint-disable-next-line no-undef 177 jQuery 178 .post( PaypalExpressCheckout.getCreatePaymentEndpoint( blogId ), payload ) 179 .done( function ( paymentResponse ) { 180 if ( ! paymentResponse ) { 181 PaypalExpressCheckout.showError( 182 PaypalExpressCheckout.processErrorMessage(), 183 domId 184 ); 185 return reject( new Error( 'server_error' ) ); 186 } 187 188 resolve( paymentResponse.id ); 189 } ) 190 .fail( function ( paymentError ) { 191 const paymentErrorMessage = 192 PaypalExpressCheckout.processErrorMessage( paymentError ); 193 PaypalExpressCheckout.showError( paymentErrorMessage, domId ); 194 195 const code = 196 paymentError.responseJSON && paymentError.responseJSON.code 197 ? paymentError.responseJSON.code 198 : 'server_error'; 199 200 reject( new Error( code ) ); 201 } ); 202 } ); 203 }, 204 205 onAuthorize: function ( onAuthData ) { 206 const payload = { 207 buttonId: buttonId, 208 payerId: onAuthData.payerID, 209 env: env, 210 }; 211 return new paypal.Promise( function ( resolve, reject ) { 212 // eslint-disable-next-line no-undef 213 jQuery 214 .post( 215 PaypalExpressCheckout.getExecutePaymentEndpoint( blogId, onAuthData.paymentID ), 216 payload 217 ) 218 .done( function ( authResponse ) { 219 if ( ! authResponse ) { 220 PaypalExpressCheckout.showError( 221 PaypalExpressCheckout.processErrorMessage(), 222 domId 223 ); 224 return reject( new Error( 'server_error' ) ); 225 } 226 227 PaypalExpressCheckout.showMessage( 228 PaypalExpressCheckout.processSuccessMessage( authResponse ), 229 domId 230 ); 231 resolve(); 232 } ) 233 .fail( function ( authError ) { 234 const authErrorMessage = PaypalExpressCheckout.processErrorMessage( authError ); 235 PaypalExpressCheckout.showError( authErrorMessage, domId ); 236 237 const code = 238 authError.responseJSON && authError.responseJSON.code 239 ? authError.responseJSON.code 240 : 'server_error'; 241 242 reject( new Error( code ) ); 243 } ); 244 } ); 245 }, 246 }, 247 buttonDomId 248 ); 249 }, 250}; 251; 252void ( function ( d, s, id ) { 253 var js, 254 fjs = d.getElementsByTagName( s )[ 0 ], 255 p = /^http:/.test( d.location ) ? 'http' : 'https'; 256 if ( ! d.getElementById( id ) ) { 257 js = d.createElement( s ); 258 js.id = id; 259 js.src = p + '://platform.twitter.com/widgets.js'; 260 fjs.parentNode.insertBefore( js, fjs ); 261 } 262} )( document, 'script', 'twitter-wjs' ); 263;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.