transparent.js 7.0 KB

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