微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

尝试使用 Apple Pay Web 验证商家时,不断收到“35 - error:14094418:SSLroutines:ssl3_read_bytes:tlsv1 alert unknown ca”

如何解决尝试使用 Apple Pay Web 验证商家时,不断收到“35 - error:14094418:SSLroutines:ssl3_read_bytes:tlsv1 alert unknown ca”

TLDR:由于某种原因我无法通过商家验证,我认为可能是


一个多月以来,我一直在努力使我的 Apple Pay 应用程序正常工作,最终决定寻求帮助。


我在构建时遇到的错误

1: curlError: "无法设置私钥文件:'/home2/mattmson/public_html/gwApplePayDev/certs/gwApplePay.key.pem' type PEM"

2: Unhandled Promise Rejection: InvalidAccessError: 对象不支持操作或参数


我从 curl_test.PHP 文件中得到的错误

    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
  1. 证书有问题(遵循 https://github.com/norfolkmustard/ApplePayJS 的教程)
  2. 我的服务器上的文件权限有问题
  3. 我的 cUrl 尝试有问题​​

这是我的 index.PHP 文件

<?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>

这是我的 apple_pay_conf.PHP 文件代码

    <?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');
    ?>

这是我的curl_test.PHP文件

<?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 举报,一经查实,本站将立刻删除。