问题描述
TLDR:由于某种原因我无法通过商家验证,我认为可能是
一个多月以来,我一直在努力使我的 Apple Pay 应用程序正常工作,最终决定寻求帮助。
我在构建时遇到的错误:
1: curlError: "无法设置私钥文件:'/home2/mattmson/public_html/gwApplePayDev/certs/gwApplePay.key.pem' type PEM"
2: Unhandled Promise Rejection: InvalidAccessError: 对象不支持操作或参数
cURL Error
35 - error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unkNown ca
Verbose information
* Trying 17.171.78.7:443...
* Connected to apple-pay-gateway.apple.com (17.171.78.7) port 443 (#0)
* ALPN,offering h2
* ALPN,offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
* CApath: none
* error:14094418:SSL routines:ssl3_read_bytes:tlsv1 alert unkNown ca
* Closing connection 0
- 证书有问题(遵循 https://github.com/norfolkmustard/ApplePayJS 的教程)
- 我的服务器上的文件权限有问题
- 我的 cUrl 尝试有问题
<?PHP
require_once ('my-path-to/apple_pay_conf.PHP');
?>
<!DOCTYPE html>
<html lang="en-GB">
<head>
<Meta charset="utf-8">
<Meta name="viewport" content="width=device-width,initial-scale=1">
<title>ApplePay Test</title>
<style>
#applePay {
width: 150px;
height: 50px;
display: none;
border-radius: 5px;
margin-left: auto;
margin-right: auto;
margin-top: 20px;
background-image: -webkit-named-image(apple-pay-logo-white);
background-position: 50% 50%;
background-color: black;
background-size: 60%;
background-repeat: no-repeat;
}
</style>
</head>
<body>
<div>
<button type="button" id="applePay"></button>
<p style="display:none" id="got_notactive">ApplePay is possible on this browser,but not currently activated.</p>
<p style="display:none" id="notgot">ApplePay is not available on this browser</p>
<p style="display:none" id="success">Test transaction completed,thanks. <a href="<?=$_SERVER["SCRIPT_URL"]?>">reset</a></p>
</div>
<script type="text/javascript">
var debug = <?=DEBUG?>;
if (window.ApplePaySession) {
var merchantIdentifier = '<?=PRODUCTION_MERCHANTIDENTIFIER?>';
var promise = ApplePaySession.canMakePaymentsWithActiveCard(merchantIdentifier);
promise.then(function (canMakePayments) {
if (canMakePayments) {
document.getElementById("applePay").style.display = "block";
logit('hi,I can do ApplePay');
} else {
document.getElementById("got_notactive").style.display = "block";
logit('ApplePay is possible on this browser,but not currently activated.');
}
});
} else {
logit('ApplePay is not available on this browser');
document.getElementById("notgot").style.display = "block";
}
document.getElementById("applePay").onclick = function(evt) {
var runningAmount = 42;
var runningPP = 0; getShippingCosts('domestic_std',true);
var runningTotal = function() { return runningAmount + runningPP; }
var shippingOption = "";
var subTotalDescr = "Test Goodies";
function getShippingOptions(shippingCountry){
logit('getShippingOptions: ' + shippingCountry );
if( shippingCountry.toupperCase() == "<?=PRODUCTION_COUNTRYCODE?>" ) {
shippingOption = [{label: 'Standard Shipping',amount: getShippingCosts('domestic_std',true),detail: '3-5 days',identifier: 'domestic_std'},{label: 'Expedited Shipping',amount: getShippingCosts('domestic_exp',false),detail: '1-3 days',identifier: 'domestic_exp'}];
} else {
shippingOption = [{label: 'International Shipping',amount: getShippingCosts('international',detail: '5-10 days',identifier: 'international'}];
}
}
function getShippingCosts(shippingIdentifier,updateRunningPP ){
var shippingCost = 0;
switch(shippingIdentifier) {
case 'domestic_std':
shippingCost = 3;
break;
case 'domestic_exp':
shippingCost = 6;
break;
case 'international':
shippingCost = 9;
break;
default:
shippingCost = 11;
}
if (updateRunningPP == true) {
runningPP = shippingCost;
}
logit('getShippingCosts: ' + shippingIdentifier + " - " + shippingCost +"|"+ runningPP );
return shippingCost;
}
var paymentRequest = {
currencyCode: '<?=PRODUCTION_CURRENCYCODE?>',countryCode: '<?=PRODUCTION_COUNTRYCODE?>',requiredShippingContactFields: ['postalAddress'],//requiredShippingContactFields: ['postalAddress','email','name','phone'],//requiredBillingContactFields: ['postalAddress',lineItems: [{label: subTotalDescr,amount: runningAmount },{label: 'P&P',amount: runningPP }],total: {
label: '<?=PRODUCTION_disPLAYNAME?>',amount: runningTotal()
},supportednetworks: ['amex','masterCard','visa' ],merchantCapabilities: [ 'supports3DS','supportsEMV','supportsCredit','supportsDebit' ]
};
var session = new ApplePaySession(1,paymentRequest);
// Merchant Validation
session.onvalidatemerchant = function (event) {
logit(event);
var promise = performValidation(event.validationURL);
promise.then(function (merchantSession) {
session.completeMerchantValidation(merchantSession);
});
}
function performValidation(valURL) {
return new Promise(function(resolve,reject) {
console.log('hello');
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var data = JSON.parse(this.responseText);
logit(data);
resolve(data);
};
xhr.onerror = reject;
xhr.open('GET','https://mywebsite.com/gwApplePayDev/apple_pay_comm.PHP?u=' + valURL);
xhr.send();
});
}
session.onshippingcontactselected = function(event) {
logit('starting session.onshippingcontactselected');
logit('NB: At this stage,apple only reveals the Country,Locality and 4 characters of the PostCode to protect the privacy of what is only a *prospective* customer at this point. This is enough for you to determine shipping costs,but not the full address of the customer.');
logit(event);
getShippingOptions( event.shippingContact.countryCode );
var status = ApplePaySession.STATUS_SUCCESS;
var newShippingMethods = shippingOption;
var newTotal = { type: 'final',label: '<?=PRODUCTION_disPLAYNAME?>',amount: runningTotal() };
var newLineItems =[{type: 'final',label: subTotalDescr,{type: 'final',label: 'P&P',amount: runningPP }];
session.completeShippingContactSelection(status,newShippingMethods,newTotal,newLineItems );
}
session.onshippingmethodselected = function(event) {
logit('starting session.onshippingmethodselected');
logit(event);
getShippingCosts( event.shippingMethod.identifier,true );
var status = ApplePaySession.STATUS_SUCCESS;
var newTotal = { type: 'final',amount: runningPP }];
session.completeShippingMethodSelection(status,newLineItems );
}
session.onpaymentmethodselected = function(event) {
logit('starting session.onpaymentmethodselected');
logit(event);
var newTotal = { type: 'final',amount: runningPP }];
session.completePaymentMethodSelection( newTotal,newLineItems );
}
session.onpaymentauthorized = function (event) {
logit('starting session.onpaymentauthorized');
logit('NB: This is the first stage when you get the *full shipping address* of the customer,in the event.payment.shippingContact object');
logit(event);
var promise = sendPaymentToken(event.payment.token);
promise.then(function (success) {
var status;
if (success){
status = ApplePaySession.STATUS_SUCCESS;
document.getElementById("applePay").style.display = "none";
document.getElementById("success").style.display = "block";
} else {
status = ApplePaySession.STATUS_FAILURE;
}
logit( "result of sendPaymentToken() function = " + success );
session.completePayment(status);
});
}
function sendPaymentToken(paymentToken) {
return new Promise(function(resolve,reject) {
logit('starting function sendPaymentToken()');
logit(paymentToken);
logit("this is where you would pass the payment token to your third-party payment provider to use the token to charge the card. Only if your provider tells you the payment was successful should you return a resolve(true) here. Otherwise reject;");
logit("defaulting to resolve(true) here,just to show what a successfully completed transaction flow looks like");
if ( debug == true )
resolve(true);
else
reject;
});
}
session.oncancel = function(event) {
logit('starting session.cancel');
logit(event);
}
session.begin();
};
function logit( data ){
if( debug == true ){
console.log(data);
}
};
</script>
</body>
</html>
<?PHP
// update these with the real location of your two .pem files. keep them above/outside your webroot folder
define('PRODUCTION_CERTIFICATE_KEY','path-to/certs/apple_pay.crt.pem');
define('PRODUCTION_CERTIFICATE_PATH','path-to/certs/merch_id.crt.pem');
define('PRODUCTION_CERTIFICATE_KEY_PASS','password');
define('PRODUCTION_MERCHANTIDENTIFIER','merchant.com.mysite.myCompany');
define('PRODUCTION_DOMAINNAME','mysite.com');
define('PRODUCTION_CURRENCYCODE','USD'); // https://en.wikipedia.org/wiki/ISO_4217
define('PRODUCTION_COUNTRYCODE','US'); // https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
define('PRODUCTION_disPLAYNAME','My Company');
define('DEBUG','true');
?>
<?PHP
error_reporting(E_ALL);
ini_set("display_errors",1);
if (!function_exists('json_last_error_msg')) {
function json_last_error_msg() {
static $ERRORS = array(
JSON_ERROR_NONE => 'No error',JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)',JSON_ERROR_CTRL_CHAR => 'Control character error,possibly incorrectly encoded',JSON_ERROR_Syntax => 'Syntax error',JSON_ERROR_UTF8 => 'Malformed UTF-8 characters,possibly incorrectly encoded'
);
$error = json_last_error();
return isset($ERRORS[$error]) ? $ERRORS[$error] : 'UnkNown error';
}
}
$validation_url = isset( $_GET['u'] ) ? $_GET['u'] : "https://apple-pay-gateway.apple.com/paymentservices/paymentSession";
if( "https" == parse_url($validation_url,PHP_URL_SCHEME) && substr( parse_url($validation_url,PHP_URL_HOST),-10 ) == ".apple.com" ){
require_once ('mypathto/apple_pay_conf.PHP');
if( !defined( 'DEBUG' ) || DEBUG != 'true' ) { exit( 'this page intentionally left blank' ); }
echo "<pre>";
// create a new cURL resource
$ch = curl_init();
$data = '{"merchantIdentifier":"'.PRODUCTION_MERCHANTIDENTIFIER.'","domainName":"'.PRODUCTION_DOMAINNAME.'","displayName":"'.PRODUCTION_disPLAYNAME.'"}';
echo "<fieldset style='padding:1em;margin:1em'><legend> data sent to applePay server </legend>$data</fieldset>";
curl_setopt($ch,CURLOPT_URL,$validation_url);
//curl_setopt($ch,CURLOPT_SSL_CIPHER_LIST,'ecdhe_rsa_aes_128_gcm_sha_256,rsa_aes_128_gcm_sha_256');
curl_setopt($ch,CURLOPT_SSLCERT,PRODUCTION_CERTIFICATE_PATH);
curl_setopt($ch,CURLOPT_SSLKEY,PRODUCTION_CERTIFICATE_KEY);
curl_setopt($ch,CURLOPT_SSLKEYPASSWD,PRODUCTION_CERTIFICATE_KEY_PASS);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
//debug options
curl_setopt($ch,CURLOPT_HEADER,true);
curl_setopt($ch,CURLOPT_VERBOSE,true);
$verbose = fopen('PHP://temp','w+');
curl_setopt($ch,CURLOPT_STDERR,$verbose);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$result = curl_exec($ch);
if( $result === false)
{
echo "<fieldset style='padding:1em;margin:1em'><legend> cURL Error </legend>";
echo curl_errno($ch) . " - " . curl_error($ch);
echo "</fieldset>";
} else {
echo "<fieldset style='padding:1em;margin:1em'><legend> applePay server response </legend>";
echo $result;
echo "</fieldset>";
echo "<fieldset style='padding:1em;margin:1em'><legend> applePay server response - JSON decode test </legend>";
print_r( json_decode( $result,true ) );
echo "<hr> JSON decode last error :- ";
echo json_last_error_msg();
echo "</fieldset>";
}
// close cURL resource,and free up system resources
rewind($verbose);
$verboseLog = stream_get_contents($verbose);
echo "<fieldset style='padding:1em;margin:1em'><legend> Verbose information </legend>";
echo htmlspecialchars($verboseLog);
echo "</fieldset>";
$version = curl_version();
echo "<fieldset style='padding:1em;margin:1em'><legend> curl version </legend>";
print_r( $version );
echo "</fieldset></pre>";
curl_close($ch);
}
?>
任何帮助将不胜感激
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)