paypal-express-checkout.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /**
  2. * This PaypalExpressCheckout global is included by wp_enqueue_script( '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. /* global paypal */
  7. /* global jQuery */
  8. /* exported PaypalExpressCheckout */
  9. /* jshint unused:false, es3:false, esversion:5 */
  10. var PaypalExpressCheckout = {
  11. primaryCssClassName: 'jetpack-simple-payments',
  12. messageCssClassName: 'jetpack-simple-payments-purchase-message',
  13. wpRestAPIHost: 'https://public-api.wordpress.com',
  14. wpRestAPIVersion: '/wpcom/v2',
  15. getEnvironment: function() {
  16. if ( localStorage && localStorage.getItem && localStorage.getItem( 'simple-payments-env' ) === 'sandbox' ) {
  17. return 'sandbox';
  18. }
  19. return 'production';
  20. },
  21. getCreatePaymentEndpoint: function( blogId ) {
  22. return PaypalExpressCheckout.wpRestAPIHost + PaypalExpressCheckout.wpRestAPIVersion + '/sites/' + blogId + '/simple-payments/paypal/payment';
  23. },
  24. getExecutePaymentEndpoint: function( blogId, paymentId ) {
  25. return PaypalExpressCheckout.wpRestAPIHost + PaypalExpressCheckout.wpRestAPIVersion + '/sites/' + blogId + '/simple-payments/paypal/' + paymentId + '/execute';
  26. },
  27. getNumberOfItems: function( field, enableMultiple ) {
  28. if ( enableMultiple !== '1' ) {
  29. return 1;
  30. }
  31. var numberField = document.getElementById( field );
  32. if ( ! numberField ) {
  33. return 1;
  34. }
  35. var number = Number( numberField.value );
  36. if ( isNaN( number ) ) {
  37. return 1;
  38. }
  39. return number;
  40. },
  41. /**
  42. * Get the DOM element-placeholder used to show message
  43. * about the transaction. If it doesn't exist then the function will create a new one.
  44. *
  45. * @param string domId id of the payment button placeholder
  46. * @return Element the dom element to print the message
  47. */
  48. getMessageContainer: function( domId ) {
  49. return document.getElementById( domId + '-message-container' );
  50. },
  51. /**
  52. * Show a messange close to the Paypal button.
  53. * Use this function to give feedback to the user according
  54. * to the transaction result.
  55. *
  56. * @param {String} message message to show
  57. * @param {String} domId paypal-button element dom identifier
  58. * @param {Boolean} [error] defines if it's a message error. Not TRUE as default.
  59. */
  60. showMessage: function( message, domId, isError ) {
  61. var domEl = PaypalExpressCheckout.getMessageContainer( domId );
  62. // set css classes
  63. var cssClasses = PaypalExpressCheckout.messageCssClassName + ' show ';
  64. cssClasses += isError ? 'error' : 'success';
  65. // show message 1s after PayPal popup is closed
  66. setTimeout( function() {
  67. domEl.innerHTML = message;
  68. domEl.setAttribute( 'class', cssClasses );
  69. }, 1000 );
  70. },
  71. showError: function( message, domId ) {
  72. PaypalExpressCheckout.showMessage( message, domId, true );
  73. },
  74. processErrorMessage: function( errorResponse ) {
  75. var error = errorResponse ? errorResponse.responseJSON : null;
  76. var defaultMessage = 'There was an issue processing your payment.';
  77. if ( ! error ) {
  78. return '<p>' + defaultMessage + '</p>';
  79. }
  80. if ( error.additional_errors ) {
  81. var messages = [];
  82. error.additional_errors.forEach( function( additionalError ) {
  83. if ( additionalError.message ) {
  84. messages.push( '<p>' + additionalError.message.toString() + '</p>' );
  85. }
  86. } );
  87. return messages.join('');
  88. }
  89. return '<p>' + ( error.message || defaultMessage ) + '</p>';
  90. },
  91. processSuccessMessage: function( successResponse ) {
  92. var message = successResponse.message;
  93. var defaultMessage = 'Thank you. Your purchase was successful!';
  94. if ( ! message ) {
  95. return '<p>' + defaultMessage + '</p>';
  96. }
  97. return '<p>' + message + '</p>';
  98. },
  99. cleanAndHideMessage: function( domId ) {
  100. var domEl = PaypalExpressCheckout.getMessageContainer( domId );
  101. domEl.setAttribute( 'class', PaypalExpressCheckout.messageCssClassName );
  102. domEl.innerHTML = '';
  103. },
  104. renderButton: function( blogId, buttonId, domId, enableMultiple ) {
  105. var env = PaypalExpressCheckout.getEnvironment();
  106. if ( ! paypal ) {
  107. throw new Error( 'PayPal module is required by PaypalExpressCheckout' );
  108. }
  109. var buttonDomId = domId + '_button';
  110. paypal.Button.render( {
  111. env: env,
  112. commit: true,
  113. style: {
  114. label: 'pay',
  115. shape: 'rect',
  116. color: 'silver',
  117. fundingicons: true,
  118. },
  119. payment: function() {
  120. PaypalExpressCheckout.cleanAndHideMessage( domId );
  121. var payload = {
  122. number: PaypalExpressCheckout.getNumberOfItems( domId + '_number', enableMultiple ),
  123. buttonId: buttonId,
  124. env: env
  125. };
  126. return new paypal.Promise( function( resolve, reject ) {
  127. jQuery.post( PaypalExpressCheckout.getCreatePaymentEndpoint( blogId ), payload )
  128. .done( function( paymentResponse ) {
  129. if ( ! paymentResponse ) {
  130. PaypalExpressCheckout.showError( PaypalExpressCheckout.processErrorMessage(), domId );
  131. return reject( new Error( 'server_error' ) );
  132. }
  133. resolve( paymentResponse.id );
  134. } )
  135. .fail( function( paymentError ) {
  136. var paymentErrorMessage = PaypalExpressCheckout.processErrorMessage( paymentError );
  137. PaypalExpressCheckout.showError( paymentErrorMessage, domId );
  138. var code = paymentError.responseJSON && paymentError.responseJSON.code ?
  139. paymentError.responseJSON.code : 'server_error';
  140. reject( new Error( code ) );
  141. } );
  142. } );
  143. },
  144. onAuthorize: function( onAuthData ) {
  145. var payload = {
  146. buttonId: buttonId,
  147. payerId: onAuthData.payerID,
  148. env: env
  149. };
  150. return new paypal.Promise( function( resolve, reject ) {
  151. jQuery.post( PaypalExpressCheckout.getExecutePaymentEndpoint( blogId, onAuthData.paymentID ), payload )
  152. .done( function( authResponse ) {
  153. if ( ! authResponse ) {
  154. PaypalExpressCheckout.showError( PaypalExpressCheckout.processErrorMessage(), domId );
  155. return reject( new Error( 'server_error' ) );
  156. }
  157. PaypalExpressCheckout.showMessage(
  158. PaypalExpressCheckout.processSuccessMessage( authResponse ),
  159. domId
  160. );
  161. resolve();
  162. } )
  163. .fail( function( authError ) {
  164. var authErrorMessage = PaypalExpressCheckout.processErrorMessage( authError );
  165. PaypalExpressCheckout.showError( authErrorMessage, domId );
  166. var code = authError.responseJSON && authError.responseJSON.code ?
  167. authError.responseJSON.code : 'server_error';
  168. reject( new Error( code ) );
  169. } );
  170. } );
  171. }
  172. }, buttonDomId );
  173. }
  174. };