Compare commits
3 Commits
31557c826c
...
b894a94133
| Author | SHA1 | Date | |
|---|---|---|---|
| b894a94133 | |||
|
|
ea828cf99c | ||
|
|
ce18a5eb1c |
@ -15,6 +15,7 @@ using Nop.Services.Payments;
|
|||||||
using Nop.Services.Plugins;
|
using Nop.Services.Plugins;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace Nop.Plugin.Payments.TapPay;
|
namespace Nop.Plugin.Payments.TapPay;
|
||||||
|
|
||||||
@ -89,10 +90,30 @@ public class TapPayPaymentProcessor : BasePlugin, IPaymentMethod
|
|||||||
var customer = await _customerService.GetCustomerByIdAsync(processPaymentRequest.CustomerId);
|
var customer = await _customerService.GetCustomerByIdAsync(processPaymentRequest.CustomerId);
|
||||||
var customerBillingAddress = await _customerService.GetCustomerBillingAddressAsync(customer);
|
var customerBillingAddress = await _customerService.GetCustomerBillingAddressAsync(customer);
|
||||||
|
|
||||||
|
string GetCustomValue(string key)
|
||||||
|
{
|
||||||
|
if (processPaymentRequest.CustomValues.TryGetValue(key, out var value) && value != null)
|
||||||
|
return value.ToString().Trim();
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var prime = GetCustomValue("Prime");
|
||||||
|
if (string.IsNullOrEmpty(prime))
|
||||||
|
{
|
||||||
|
result.AddError("TapPay prime is missing.");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cardholderEmail = GetCustomValue("CardholderEmail");
|
||||||
|
var cardholderPhone = GetCustomValue("CardholderPhoneNumber");
|
||||||
|
var cardholderPhoneCode = GetCustomValue("CardholderPhoneNumberCountryCode");
|
||||||
|
var cardholderNameEn = GetCustomValue("CardholderNameEn");
|
||||||
|
|
||||||
var requestBody = JsonSerializer.Serialize(
|
var requestBody = JsonSerializer.Serialize(
|
||||||
new {
|
new {
|
||||||
partner_key = _tapPayPaymentSettings.PartnerKey,
|
partner_key = _tapPayPaymentSettings.PartnerKey,
|
||||||
prime = ((Newtonsoft.Json.Linq.JArray)processPaymentRequest.CustomValues["Prime"])[0].ToString(),
|
prime = prime,
|
||||||
amount = (int)processPaymentRequest.OrderTotal,
|
amount = (int)processPaymentRequest.OrderTotal,
|
||||||
merchant_id = _tapPayPaymentSettings.Merchant.ToString(),
|
merchant_id = _tapPayPaymentSettings.Merchant.ToString(),
|
||||||
order_number = processPaymentRequest.OrderGuid.ToString(),
|
order_number = processPaymentRequest.OrderGuid.ToString(),
|
||||||
@ -105,11 +126,13 @@ public class TapPayPaymentProcessor : BasePlugin, IPaymentMethod
|
|||||||
},
|
},
|
||||||
details = "AI Hardware / APP",
|
details = "AI Hardware / APP",
|
||||||
cardholder = new {
|
cardholder = new {
|
||||||
phone_number = customerBillingAddress.PhoneNumber,
|
phone_number = cardholderPhone,
|
||||||
name = customerBillingAddress.LastName + customerBillingAddress.FirstName,
|
phone_number_country_code = string.IsNullOrWhiteSpace(cardholderPhoneCode) ? "886" : cardholderPhoneCode,
|
||||||
email = customerBillingAddress.Email,
|
name_en = cardholderNameEn,
|
||||||
zip_code = customerBillingAddress.ZipPostalCode,
|
name = (customerBillingAddress?.LastName ?? string.Empty) + (customerBillingAddress?.FirstName ?? string.Empty),
|
||||||
address = customerBillingAddress.City + customerBillingAddress.Address1 + customerBillingAddress.Address2,
|
email = cardholderEmail,
|
||||||
|
zip_code = customerBillingAddress?.ZipPostalCode,
|
||||||
|
address = (customerBillingAddress?.City ?? string.Empty) + (customerBillingAddress?.Address1 ?? string.Empty) + (customerBillingAddress?.Address2 ?? string.Empty),
|
||||||
member_id = processPaymentRequest.CustomerId.ToString()
|
member_id = processPaymentRequest.CustomerId.ToString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,7 +390,11 @@ public class TapPayPaymentProcessor : BasePlugin, IPaymentMethod
|
|||||||
public Task<ProcessPaymentRequest> GetPaymentInfoAsync(IFormCollection form)
|
public Task<ProcessPaymentRequest> GetPaymentInfoAsync(IFormCollection form)
|
||||||
{
|
{
|
||||||
var paymentRequest = new ProcessPaymentRequest();
|
var paymentRequest = new ProcessPaymentRequest();
|
||||||
paymentRequest.CustomValues.Add("Prime", form["Prime"]);
|
paymentRequest.CustomValues.Add("Prime", form["Prime"].ToString());
|
||||||
|
paymentRequest.CustomValues.Add("CardholderEmail", form["CardholderEmail"].ToString());
|
||||||
|
paymentRequest.CustomValues.Add("CardholderPhoneNumber", form["CardholderPhoneNumber"].ToString());
|
||||||
|
paymentRequest.CustomValues.Add("CardholderPhoneNumberCountryCode", form["CardholderPhoneNumberCountryCode"].ToString());
|
||||||
|
paymentRequest.CustomValues.Add("CardholderNameEn", form["CardholderNameEn"].ToString());
|
||||||
return Task.FromResult(paymentRequest);
|
return Task.FromResult(paymentRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,4 +509,4 @@ public class TapPayPaymentProcessor : BasePlugin, IPaymentMethod
|
|||||||
public bool SkipPaymentInfo => false;
|
public bool SkipPaymentInfo => false;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,20 +3,75 @@
|
|||||||
}
|
}
|
||||||
@model Nop.Plugin.Payments.TapPay.Models.PaymentInfoModel
|
@model Nop.Plugin.Payments.TapPay.Models.PaymentInfoModel
|
||||||
|
|
||||||
@* <!script async src="https://js.tappaysdk.com/tpdirect/v5.1.0"></!script> *@
|
|
||||||
|
|
||||||
<input type="hidden" asp-for="AppId" />
|
<input type="hidden" asp-for="AppId" />
|
||||||
<input type="hidden" asp-for="AppKey" />
|
<input type="hidden" asp-for="AppKey" />
|
||||||
<input type="hidden" asp-for="ServerType" />
|
<input type="hidden" asp-for="ServerType" />
|
||||||
<input type="hidden" id="Prime" name="Prime" />
|
<input type="hidden" id="Prime" name="Prime" />
|
||||||
|
|
||||||
<table width="100%" cellspacing="2" cellpadding="1" border="0">
|
<style>
|
||||||
|
.tappay-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: separate;
|
||||||
|
border-spacing: 2px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tappay-table label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tappay-table .form-control,
|
||||||
|
.tappay-table .tappay-input {
|
||||||
|
height: 38px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: border-color .2s ease, color .2s ease, box-shadow .2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tappay-table .tappay-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tappay-table .has-error .form-control,
|
||||||
|
.tappay-table .has-error .tappay-input {
|
||||||
|
border-color: #e74c3c;
|
||||||
|
color: #e74c3c;
|
||||||
|
box-shadow: 0 0 0 1px rgba(231, 76, 60, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tappay-table .has-success .form-control,
|
||||||
|
.tappay-table .has-success .tappay-input {
|
||||||
|
border-color: #2ecc71;
|
||||||
|
color: #2ecc71;
|
||||||
|
box-shadow: 0 0 0 1px rgba(46, 204, 113, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tappay-table .phone-wrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tappay-table .country-code-input {
|
||||||
|
max-width: 70px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tappay-table .country-prefix {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<table class="tappay-table" width="100%" cellspacing="2" cellpadding="1" border="0">
|
||||||
<tr class="card-number-group">
|
<tr class="card-number-group">
|
||||||
<td>
|
<td>
|
||||||
<label><span id="cardtype"></span>@T("Payment.CardNumber"):</label>
|
<label><span id="cardtype"></span>@T("Payment.CardNumber"):</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="form-control card-number" style="height: 20px"></div>
|
<div class="form-control card-number"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="expiration-date-group">
|
<tr class="expiration-date-group">
|
||||||
@ -24,7 +79,7 @@
|
|||||||
<label>@T("Payment.ExpirationDate"):</label>
|
<label>@T("Payment.ExpirationDate"):</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="form-control expiration-date" style="height: 20px"></div>
|
<div class="form-control expiration-date"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="ccv-group">
|
<tr class="ccv-group">
|
||||||
@ -32,140 +87,288 @@
|
|||||||
<label>@T("Payment.CardCode"):</label>
|
<label>@T("Payment.CardCode"):</label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="form-control ccv" style="height: 20px"></div>
|
<div class="form-control ccv"></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="name-en-group">
|
||||||
|
<td>
|
||||||
|
<label>@T("Payment.CardHolderName"):</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input class="tappay-input" type="text" id="CardholderNameEn" name="CardholderNameEn" maxlength="45" placeholder="@T("Payment.CardHolderName")"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="email-group">
|
||||||
|
<td>
|
||||||
|
<label>@T("Payment.CardHolderEmail"):</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input class="tappay-input" type="text" id="CardholderEmail" name="CardholderEmail" maxlength="40" placeholder="@T("Payment.CardHolderEmail")"/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="phone_group">
|
||||||
|
<td>
|
||||||
|
<label>@T("Payment.CardHolderPhone"):</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="phone-wrapper">
|
||||||
|
<div class="phone-code-group">
|
||||||
|
<span class="country-prefix">+</span>
|
||||||
|
<input class="tappay-input country-code-input" type="tel" id="CardholderPhoneNumberCountryCode" name="CardholderPhoneNumberCountryCode" minlength="1" maxlength="4" placeholder="886" value="886"/>
|
||||||
|
</div>
|
||||||
|
<div class="phone-number-group">
|
||||||
|
<input class="tappay-input phone-number-input" type="tel" id="CardholderPhoneNumber" name="CardholderPhoneNumber" maxlength="16" placeholder="912345678"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<script asp-location="Footer">
|
<script asp-location="Footer">
|
||||||
//$(document).ready(function() {
|
var tappayCustomFieldState = {
|
||||||
$.getScript("https://js.tappaysdk.com/tpdirect/v5.1.0", function() {
|
nameEn: { valid: false, dirty: false },
|
||||||
TPDirect.setupSDK($('#AppId').val(), $('#AppKey').val(), $('#ServerType').val());
|
email: { valid: false, dirty: false },
|
||||||
$('.button-1.payment-info-next-step-button').attr('disabled', true);
|
phoneCode: { valid: false, dirty: false },
|
||||||
$('.button-1.payment-info-next-step-button').removeAttr('onclick');
|
phoneNumber: { valid: false, dirty: false }
|
||||||
$('.button-1.payment-info-next-step-button').off('click');
|
};
|
||||||
$('.button-1.payment-info-next-step-button').click(function() {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
// fix keyboard issue in iOS device
|
|
||||||
forceBlurIos();
|
|
||||||
|
|
||||||
const tappayStatus = TPDirect.card.getTappayFieldsStatus();
|
|
||||||
console.log(tappayStatus);
|
|
||||||
|
|
||||||
// Check TPDirect.card.getTappayFieldsStatus().canGetPrime before TPDirect.card.getPrime
|
var tappayCanGetPrime = false;
|
||||||
if (tappayStatus.canGetPrime === false) {
|
|
||||||
alert('can not get prime');
|
function setGroupState(selector, isValid, isDirty) {
|
||||||
return;
|
var group = $(selector);
|
||||||
}
|
group.removeClass('has-error has-success');
|
||||||
|
if (isDirty) {
|
||||||
TPDirect.card.getPrime(function (result) {
|
group.addClass(isValid ? 'has-success' : 'has-error');
|
||||||
if (result.status !== 0) {
|
}
|
||||||
alert('get prime error ' + result.msg);
|
}
|
||||||
|
|
||||||
|
function validateNameEn(markDirty) {
|
||||||
|
var value = $('#CardholderNameEn').val().trim();
|
||||||
|
tappayCustomFieldState.nameEn.dirty = tappayCustomFieldState.nameEn.dirty || markDirty || value.length > 0;
|
||||||
|
tappayCustomFieldState.nameEn.valid = /^[A-Za-z]+(?:[\s'-][A-Za-z]+)*$/.test(value) && value.length > 1;
|
||||||
|
setGroupState('.name-en-group', tappayCustomFieldState.nameEn.valid, tappayCustomFieldState.nameEn.dirty);
|
||||||
|
return tappayCustomFieldState.nameEn.valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateEmail(markDirty) {
|
||||||
|
var value = $('#CardholderEmail').val().trim();
|
||||||
|
tappayCustomFieldState.email.dirty = tappayCustomFieldState.email.dirty || markDirty || value.length > 0;
|
||||||
|
tappayCustomFieldState.email.valid = /^[^\s@@]+@@[^\s@@]+\.[^\s@@]+$/.test(value);
|
||||||
|
setGroupState('.email-group', tappayCustomFieldState.email.valid, tappayCustomFieldState.email.dirty);
|
||||||
|
return tappayCustomFieldState.email.valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validatePhoneCode(markDirty) {
|
||||||
|
var value = $('#CardholderPhoneNumberCountryCode').val().trim();
|
||||||
|
tappayCustomFieldState.phoneCode.dirty = tappayCustomFieldState.phoneCode.dirty || markDirty || value.length > 0;
|
||||||
|
tappayCustomFieldState.phoneCode.valid = /^\d{1,4}$/.test(value);
|
||||||
|
setGroupState('#phone_group .phone-code-group', tappayCustomFieldState.phoneCode.valid, tappayCustomFieldState.phoneCode.dirty);
|
||||||
|
return tappayCustomFieldState.phoneCode.valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validatePhoneNumber(markDirty) {
|
||||||
|
var value = $('#CardholderPhoneNumber').val().trim();
|
||||||
|
tappayCustomFieldState.phoneNumber.dirty = tappayCustomFieldState.phoneNumber.dirty || markDirty || value.length > 0;
|
||||||
|
tappayCustomFieldState.phoneNumber.valid = /^\d{4,16}$/.test(value);
|
||||||
|
setGroupState('#phone_group .phone-number-group', tappayCustomFieldState.phoneNumber.valid, tappayCustomFieldState.phoneNumber.dirty);
|
||||||
|
return tappayCustomFieldState.phoneNumber.valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function areCustomFieldsValid(markDirty) {
|
||||||
|
var nameValid = validateNameEn(markDirty);
|
||||||
|
var emailValid = validateEmail(markDirty);
|
||||||
|
var phoneCodeValid = validatePhoneCode(markDirty);
|
||||||
|
var phoneNumberValid = validatePhoneNumber(markDirty);
|
||||||
|
|
||||||
|
return nameValid && emailValid && phoneCodeValid && phoneNumberValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSubmitButton(canGetPrime) {
|
||||||
|
if (typeof canGetPrime === 'boolean') {
|
||||||
|
tappayCanGetPrime = canGetPrime;
|
||||||
|
}
|
||||||
|
var canSubmit = tappayCanGetPrime && areCustomFieldsValid(false);
|
||||||
|
$('.button-1.payment-info-next-step-button').prop('disabled', !canSubmit);
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
$('#CardholderNameEn').on('input blur', function () {
|
||||||
|
validateNameEn(true);
|
||||||
|
updateSubmitButton();
|
||||||
|
});
|
||||||
|
$('#CardholderEmail').on('input blur', function () {
|
||||||
|
validateEmail(true);
|
||||||
|
updateSubmitButton();
|
||||||
|
});
|
||||||
|
$('#CardholderPhoneNumberCountryCode').on('input blur', function () {
|
||||||
|
validatePhoneCode(true);
|
||||||
|
updateSubmitButton();
|
||||||
|
});
|
||||||
|
$('#CardholderPhoneNumber').on('input blur', function () {
|
||||||
|
validatePhoneNumber(true);
|
||||||
|
updateSubmitButton();
|
||||||
|
});
|
||||||
|
|
||||||
|
// initialize default validation state
|
||||||
|
validatePhoneCode(false);
|
||||||
|
updateSubmitButton(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "https://js.tappaysdk.com/sdk/tpdirect/v5.24.0",
|
||||||
|
dataType: "script",
|
||||||
|
cache: true,
|
||||||
|
success: function() {
|
||||||
|
TPDirect.setupSDK($('#AppId').val(), $('#AppKey').val(), $('#ServerType').val());
|
||||||
|
$('.button-1.payment-info-next-step-button').prop('disabled', true);
|
||||||
|
$('.button-1.payment-info-next-step-button').removeAttr('onclick');
|
||||||
|
$('.button-1.payment-info-next-step-button').off('click');
|
||||||
|
$('.button-1.payment-info-next-step-button').click(function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// fix keyboard issue in iOS device
|
||||||
|
forceBlurIos();
|
||||||
|
|
||||||
|
const tappayStatus = TPDirect.card.getTappayFieldsStatus();
|
||||||
|
console.log(tappayStatus);
|
||||||
|
|
||||||
|
tappayCanGetPrime = tappayStatus.canGetPrime;
|
||||||
|
|
||||||
|
if (!areCustomFieldsValid(true)) {
|
||||||
|
updateSubmitButton(tappayCanGetPrime);
|
||||||
|
alert('請完整填寫持卡人資訊');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$('#Prime').val(result.card.prime);
|
|
||||||
if(typeof PaymentInfo !== 'undefined')
|
// Check TPDirect.card.getTappayFieldsStatus().canGetPrime before TPDirect.card.getPrime
|
||||||
{
|
if (tappayStatus.canGetPrime === false) {
|
||||||
PaymentInfo.save();
|
alert('can not get prime');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
TPDirect.card.getPrime(function (result) {
|
||||||
$("form[action='/checkout/paymentinfo'").submit();
|
if (result.status !== 0) {
|
||||||
|
alert('get prime error ' + result.msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$('#Prime').val(result.card.prime);
|
||||||
|
if(typeof PaymentInfo !== 'undefined')
|
||||||
|
{
|
||||||
|
PaymentInfo.save();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$("form[action='/checkout/paymentinfo'").submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
TPDirect.card.setup({
|
||||||
|
fields: {
|
||||||
|
number: {
|
||||||
|
element: '.form-control.card-number',
|
||||||
|
placeholder: '**** **** **** ****'
|
||||||
|
},
|
||||||
|
expirationDate: {
|
||||||
|
element: '.form-control.expiration-date',
|
||||||
|
placeholder: 'MM / YY'
|
||||||
|
},
|
||||||
|
ccv: {
|
||||||
|
element: '.form-control.ccv',
|
||||||
|
placeholder: '後三碼'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
@* cardholder: {
|
||||||
|
name_en: {
|
||||||
|
element: document.getElementById('name_en'),
|
||||||
|
placeholder: '持卡人姓名'
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
element: document.getElementById('email'),
|
||||||
|
placeholder: 'Email'
|
||||||
|
},
|
||||||
|
phone: {
|
||||||
|
country_code: {
|
||||||
|
element: document.getElementById('phone_country_code'),
|
||||||
|
placeholder: '886'
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
element: document.getElementById('phone_number'),
|
||||||
|
placeholder: '912345678'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}, *@
|
||||||
|
styles: {
|
||||||
|
'input': {
|
||||||
|
'color': 'gray'
|
||||||
|
},
|
||||||
|
'input.ccv': {
|
||||||
|
// 'font-size': '16px'
|
||||||
|
},
|
||||||
|
':focus': {
|
||||||
|
'color': 'black'
|
||||||
|
},
|
||||||
|
'.valid': {
|
||||||
|
'color': 'green'
|
||||||
|
},
|
||||||
|
'.invalid': {
|
||||||
|
'color': 'red'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 此設定會顯示卡號輸入正確後,會顯示前六後四碼信用卡卡號
|
||||||
|
isMaskCreditCardNumber: true,
|
||||||
|
maskCreditCardNumberRange: {
|
||||||
|
beginIndex: 6,
|
||||||
|
endIndex: 11
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
TPDirect.card.setup({
|
// listen for TapPay Field
|
||||||
fields: {
|
TPDirect.card.onUpdate(function (update) {
|
||||||
number: {
|
/* Disable / enable submit button depend on update.canGetPrime */
|
||||||
element: '.form-control.card-number',
|
/* ============================================================ */
|
||||||
placeholder: '**** **** **** ****'
|
|
||||||
},
|
// update.canGetPrime === true
|
||||||
expirationDate: {
|
// --> you can call TPDirect.card.getPrime()
|
||||||
element: '.form-control.expiration-date',
|
// const submitButton = document.querySelector('button[type="submit"]')
|
||||||
placeholder: 'MM / YY'
|
updateSubmitButton(update.canGetPrime);
|
||||||
},
|
|
||||||
ccv: {
|
/* Change card type display when card type change */
|
||||||
element: '.form-control.ccv',
|
/* ============================================== */
|
||||||
placeholder: '後三碼'
|
|
||||||
|
// cardTypes = ['visa', 'mastercard', ...]
|
||||||
|
var newType = update.cardType === 'unknown' ? '' : update.cardType.toUpperCase();
|
||||||
|
$('#cardtype').text(newType);
|
||||||
|
|
||||||
|
/* Change form-group style when tappay field status change */
|
||||||
|
/* ======================================================= */
|
||||||
|
|
||||||
|
// number 欄位是錯誤的
|
||||||
|
if (update.status.number === 2) {
|
||||||
|
setNumberFormGroupToError('.card-number-group');
|
||||||
|
} else if (update.status.number === 0) {
|
||||||
|
setNumberFormGroupToSuccess('.card-number-group');
|
||||||
|
} else {
|
||||||
|
setNumberFormGroupToNormal('.card-number-group');
|
||||||
}
|
}
|
||||||
},
|
|
||||||
styles: {
|
if (update.status.expiry === 2) {
|
||||||
'input': {
|
setNumberFormGroupToError('.expiration-date-group');
|
||||||
'color': 'gray'
|
} else if (update.status.expiry === 0) {
|
||||||
},
|
setNumberFormGroupToSuccess('.expiration-date-group');
|
||||||
'input.ccv': {
|
} else {
|
||||||
// 'font-size': '16px'
|
setNumberFormGroupToNormal('.expiration-date-group');
|
||||||
},
|
|
||||||
':focus': {
|
|
||||||
'color': 'black'
|
|
||||||
},
|
|
||||||
'.valid': {
|
|
||||||
'color': 'green'
|
|
||||||
},
|
|
||||||
'.invalid': {
|
|
||||||
'color': 'red'
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
// 此設定會顯示卡號輸入正確後,會顯示前六後四碼信用卡卡號
|
|
||||||
isMaskCreditCardNumber: true,
|
|
||||||
maskCreditCardNumberRange: {
|
|
||||||
beginIndex: 6,
|
|
||||||
endIndex: 11
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// listen for TapPay Field
|
if (update.status.ccv === 2) {
|
||||||
TPDirect.card.onUpdate(function (update) {
|
setNumberFormGroupToError('.ccv-group');
|
||||||
/* Disable / enable submit button depend on update.canGetPrime */
|
} else if (update.status.ccv === 0) {
|
||||||
/* ============================================================ */
|
setNumberFormGroupToSuccess('.ccv-group');
|
||||||
|
} else {
|
||||||
// update.canGetPrime === true
|
setNumberFormGroupToNormal('.ccv-group');
|
||||||
// --> you can call TPDirect.card.getPrime()
|
}
|
||||||
// const submitButton = document.querySelector('button[type="submit"]')
|
});
|
||||||
if (update.canGetPrime) {
|
}
|
||||||
// submitButton.removeAttribute('disabled')
|
|
||||||
$('.button-1.payment-info-next-step-button').removeAttr('disabled');
|
|
||||||
} else {
|
|
||||||
// submitButton.setAttribute('disabled', true)
|
|
||||||
$('.button-1.payment-info-next-step-button').attr('disabled', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change card type display when card type change */
|
|
||||||
/* ============================================== */
|
|
||||||
|
|
||||||
// cardTypes = ['visa', 'mastercard', ...]
|
|
||||||
var newType = update.cardType === 'unknown' ? '' : update.cardType.toUpperCase();
|
|
||||||
$('#cardtype').text(newType);
|
|
||||||
|
|
||||||
/* Change form-group style when tappay field status change */
|
|
||||||
/* ======================================================= */
|
|
||||||
|
|
||||||
// number 欄位是錯誤的
|
|
||||||
if (update.status.number === 2) {
|
|
||||||
setNumberFormGroupToError('.card-number-group');
|
|
||||||
} else if (update.status.number === 0) {
|
|
||||||
setNumberFormGroupToSuccess('.card-number-group');
|
|
||||||
} else {
|
|
||||||
setNumberFormGroupToNormal('.card-number-group');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update.status.expiry === 2) {
|
|
||||||
setNumberFormGroupToError('.expiration-date-group');
|
|
||||||
} else if (update.status.expiry === 0) {
|
|
||||||
setNumberFormGroupToSuccess('.expiration-date-group');
|
|
||||||
} else {
|
|
||||||
setNumberFormGroupToNormal('.expiration-date-group');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update.status.ccv === 2) {
|
|
||||||
setNumberFormGroupToError('.ccv-group');
|
|
||||||
} else if (update.status.ccv === 0) {
|
|
||||||
setNumberFormGroupToSuccess('.ccv-group');
|
|
||||||
} else {
|
|
||||||
setNumberFormGroupToNormal('.ccv-group');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function setNumberFormGroupToError(selector) {
|
function setNumberFormGroupToError(selector) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user