transparent.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. /* @api */
  6. define([
  7. 'jquery',
  8. 'mage/template',
  9. 'Magento_Ui/js/modal/alert',
  10. 'jquery/ui',
  11. 'Magento_Payment/js/model/credit-card-validation/validator',
  12. 'Magento_Checkout/js/model/full-screen-loader'
  13. ], function ($, mageTemplate, alert, ui, validator, fullScreenLoader) {
  14. 'use strict';
  15. $.widget('mage.transparent', {
  16. options: {
  17. context: null,
  18. placeOrderSelector: '[data-role="review-save"]',
  19. paymentFormSelector: '#co-payment-form',
  20. updateSelectorPrefix: '#checkout-',
  21. updateSelectorSuffix: '-load',
  22. hiddenFormTmpl:
  23. '<form target="<%= data.target %>" action="<%= data.action %>" method="POST" ' +
  24. 'hidden enctype="application/x-www-form-urlencoded" class="no-display">' +
  25. '<% _.each(data.inputs, function(val, key){ %>' +
  26. '<input value="<%= val %>" name="<%= key %>" type="hidden">' +
  27. '<% }); %>' +
  28. '</form>',
  29. reviewAgreementForm: '#checkout-agreements',
  30. cgiUrl: null,
  31. orderSaveUrl: null,
  32. controller: null,
  33. gateway: null,
  34. dateDelim: null,
  35. cardFieldsMap: null,
  36. expireYearLength: 2
  37. },
  38. /**
  39. * {Function}
  40. * @private
  41. */
  42. _create: function () {
  43. this.hiddenFormTmpl = mageTemplate(this.options.hiddenFormTmpl);
  44. if (this.options.context) {
  45. this.options.context.setPlaceOrderHandler($.proxy(this._orderSave, this));
  46. this.options.context.setValidateHandler($.proxy(this._validateHandler, this));
  47. } else {
  48. $(this.options.placeOrderSelector)
  49. .off('click')
  50. .on('click', $.proxy(this._placeOrderHandler, this));
  51. }
  52. this.element.validation();
  53. $('[data-container="' + this.options.gateway + '-cc-number"]').on('focusout', function () {
  54. $(this).valid();
  55. });
  56. },
  57. /**
  58. * handler for credit card validation
  59. * @return {Boolean}
  60. * @private
  61. */
  62. _validateHandler: function () {
  63. return this.element.validation && this.element.validation('isValid');
  64. },
  65. /**
  66. * handler for Place Order button to call gateway for credit card validation
  67. * @return {Boolean}
  68. * @private
  69. */
  70. _placeOrderHandler: function () {
  71. if (this._validateHandler()) {
  72. this._orderSave();
  73. }
  74. return false;
  75. },
  76. /**
  77. * Save order and generate post data for gateway call
  78. * @private
  79. */
  80. _orderSave: function () {
  81. var postData = $(this.options.paymentFormSelector).serialize();
  82. if ($(this.options.reviewAgreementForm).length) {
  83. postData += '&' + $(this.options.reviewAgreementForm).serialize();
  84. }
  85. postData += '&controller=' + this.options.controller;
  86. postData += '&cc_type=' + this.element.find(
  87. '[data-container="' + this.options.gateway + '-cc-type"]'
  88. ).val();
  89. return $.ajax({
  90. url: this.options.orderSaveUrl,
  91. type: 'post',
  92. context: this,
  93. data: postData,
  94. dataType: 'json',
  95. /**
  96. * {Function}
  97. */
  98. beforeSend: function () {
  99. fullScreenLoader.startLoader();
  100. },
  101. /**
  102. * {Function}
  103. */
  104. success: function (response) {
  105. var preparedData,
  106. msg,
  107. /**
  108. * {Function}
  109. */
  110. alertActionHandler = function () {
  111. // default action
  112. };
  113. if (response.success && response[this.options.gateway]) {
  114. preparedData = this._preparePaymentData(
  115. response[this.options.gateway].fields,
  116. this.options.cardFieldsMap
  117. );
  118. this._postPaymentToGateway(preparedData);
  119. } else {
  120. fullScreenLoader.stopLoader(true);
  121. msg = response['error_messages'];
  122. if (this.options.context) {
  123. this.options.context.clearTimeout().fail();
  124. alertActionHandler = this.options.context.alertActionHandler;
  125. }
  126. if (typeof msg === 'object') {
  127. msg = msg.join('\n');
  128. }
  129. if (msg) {
  130. alert(
  131. {
  132. content: msg,
  133. actions: {
  134. /**
  135. * {Function}
  136. */
  137. always: alertActionHandler
  138. }
  139. }
  140. );
  141. }
  142. }
  143. }.bind(this)
  144. });
  145. },
  146. /**
  147. * Post data to gateway for credit card validation
  148. * @param {Object} data
  149. * @private
  150. */
  151. _postPaymentToGateway: function (data) {
  152. var tmpl,
  153. iframeSelector = '[data-container="' + this.options.gateway + '-transparent-iframe"]';
  154. tmpl = this.hiddenFormTmpl({
  155. data: {
  156. target: $(iframeSelector).attr('name'),
  157. action: this.options.cgiUrl,
  158. inputs: data
  159. }
  160. });
  161. $(tmpl).appendTo($(iframeSelector)).submit();
  162. },
  163. /**
  164. * Add credit card fields to post data for gateway
  165. * @param {Object} data
  166. * @param {Object} ccfields
  167. * @private
  168. */
  169. _preparePaymentData: function (data, ccfields) {
  170. var preparedata;
  171. if (this.element.find('[data-container="' + this.options.gateway + '-cc-cvv"]').length) {
  172. data[ccfields.cccvv] = this.element.find(
  173. '[data-container="' + this.options.gateway + '-cc-cvv"]'
  174. ).val();
  175. }
  176. preparedata = this._prepareExpDate();
  177. data[ccfields.ccexpdate] = preparedata.month + this.options.dateDelim + preparedata.year;
  178. data[ccfields.ccnum] = this.element.find(
  179. '[data-container="' + this.options.gateway + '-cc-number"]'
  180. ).val();
  181. return data;
  182. },
  183. /**
  184. * Grab Month and Year into one
  185. * @returns {Object}
  186. * @private
  187. */
  188. _prepareExpDate: function () {
  189. var year = this.element.find('[data-container="' + this.options.gateway + '-cc-year"]').val(),
  190. month = parseInt(
  191. this.element.find('[data-container="' + this.options.gateway + '-cc-month"]').val(),
  192. 10
  193. );
  194. if (year.length > this.options.expireYearLength) {
  195. year = year.substring(year.length - this.options.expireYearLength);
  196. }
  197. if (month < 10) {
  198. month = '0' + month;
  199. }
  200. return {
  201. month: month, year: year
  202. };
  203. }
  204. });
  205. return $.mage.transparent;
  206. });