【问题标题】:How to replace the creditCard option with nonce using Braintree?如何使用 Braintree 用 nonce 替换 creditCard 选项?
【发布时间】:2016-11-14 12:12:39
【问题描述】:

我有一个集成了 Braintree 支付网关的应用程序。我正在使用自定义表单而不是插入式 UI,我使用 creditCard 参数从客户信用卡进行一次性交易。最近发现creditCard参数已经被弃用了,引入了一个新参数paymentMethodNonce我之前的代码是

Braintree_Configuration::environment('sandbox');
Braintree_Configuration::merchantId('xxxxxx');
Braintree_Configuration::publicKey('xxxxxx');
Braintree_Configuration::privateKey('xxxxxxxxxxxxxxxxx');

$result = Braintree_Transaction::sale(array(
            'amount' => $price,
            'creditCard' => array(
                'number' => $card_number,
                'cardholderName' => $card_name,
                'expirationDate' => $expirationDate,
                'cvv' => $cvv
            )
));

根据文档,我需要使用隐藏的输入字段在表单中发送令牌以进行交易,我通过以下方式在表单中添加了令牌

<input type="hidden" name="payment_method_nonce" id="payment_method_nonce" value="<?=Braintree_ClientToken::generate()?>" />

在我提交表单的另一个页面上,我使用文档 bt 将代码更改为以下内容,但我仍然收到验证错误

付款方式令牌无效。

$payment_method_nonce   =   $_POST['payment_method_nonce'];
$result  = Braintree_Transaction::sale([
    'amount' => '25.00',
    'paymentMethodToken' => $payment_method_nonce,
    'options' => [
      'submitForSettlement' => True
    ]
  ]);

已编辑

这是更新的代码

index.php

 <?php
    include 'db.php';
    include 'functions.php';
    require_once 'braintree-php-3.13.0/lib/Braintree.php';
    Braintree_Configuration::environment('sandbox');
    Braintree_Configuration::merchantId('xxxxxx');
    Braintree_Configuration::publicKey('xxxxxxx');
    Braintree_Configuration::privateKey('xxxxxx');
    $payment_method_nonce=  Braintree_ClientToken::generate();
?>
<script type="text/javascript" src="../../public_html/js/jquery.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script type="text/javascript" src="js/jquery.creditCardValidator.js"></script>
<script type="text/javascript" src="js/card.js"></script>
<link rel="stylesheet" href="style.css">


<style>
    label, input { display:block; }
    input.text { margin-bottom:12px; width:95%; padding: .4em; }
    fieldset { padding:0; border:0; margin-top:25px; }
    h1 { font-size: 1.2em; margin: .6em 0; }
    div#users-contain { width: 350px; margin: 20px 0; }
    div#users-contain table { margin: 1em 0; border-collapse: collapse; width: 100%; }
    div#users-contain table td, div#users-contain table th { border: 1px solid #eee; padding: .6em 10px; text-align: left; }
    .ui-dialog .ui-state-error { padding: .3em; }
    .validateTips { border: 1px solid transparent; padding: 0.3em; }
</style>


<script type="text/javascript">
    //    braintree dialouge
    var form;
    $(document).ready(function () {
        dialog = $("#dialog-form").dialog({
            autoOpen: false,
            height: 500,
            width: 500,
            modal: true,
            close: function () {
                form[0].reset();
            }
        });

//        form = dialog.find("form").on("submit", function (event) {
//            event.preventDefault();
//        });

        $("#create-user").button().on("click", function () {
            dialog.dialog("open");
        });
        console.log("Here");



    });

</script>

<button name="create-user" id="create-user">Open Dialouge</button>
<div id="dialog-form" style="display:none;">
    <form method="post"  id="paymentForm" action="cardprocess.php">

        <ul>
            <li>
                <label>Card Number </label>
                <input type="text" name="card_number" id="card_number"  maxlength="20" placeholder="1234 5678 9012 3456"/>
            </li>
<!--            <li>
                <label>Name on Card</label>
                <input type="text" name="card_name" id="card_name" placeholder="Card Holder Name"/>
            </li>-->
            <li class="vertical">
                <ul>
                    <li>
                        <label>Expires</label>
                        <input type="text" name="expiry_month" id="expiry_month" maxlength="2" placeholder="MM" class="inputLeft" />
                        <input type="text" name="expiry_year" id="expiry_year" maxlength="2" placeholder="YY" class="inputLeft" />
                    </li>
                    <li>
                        <label>CVV</label>
                        <input type="text" name="cvv" id="cvv" maxlength="3" placeholder="123" class="inputLeft" />
                    </li>
                </ul>
            </li>
            <li>
                <input type="submit" id="paymentButton" value="Proceed" disabled="true" class="disable">
            </li>
        </ul>
    </form>
</div>
<div id="orderInfo"></div>
<script src="https://js.braintreegateway.com/js/braintree-2.26.0.min.js"></script>
<script type="text/javascript">
     braintree.setup('<?=$payment_method_nonce?>', 'custom', {
            id: "paymentForm",
            hostedFields: {
                number: {
                  selector: "#card_number"
                },
                expirationMonth: {
                  selector: "#expiry_month"
                },
                expirationYear: {
                  selector: "#expiry_year"
                },
                cvv: {
                  selector: "#cvv"
                },
          },
          onError:function (errorObj){
              console.log(errorObj.type);
              console.log(errorObj.message);
          }
        });
</script>

cardprocess.php

    <?php

    include 'db.php';
    include 'functions.php';       

    $price = '1000';
require_once 'braintree-php-3.13.0/lib/Braintree.php';
        Braintree_Configuration::environment('sandbox');
        Braintree_Configuration::merchantId('xxxx');
        Braintree_Configuration::publicKey('xxxx');
        Braintree_Configuration::privateKey('xxxxxxx');
    if ($_SERVER["REQUEST_METHOD"] == "POST") {

        $payment_method_nonce   =   $_POST['payment_method_nonce'];




        $result  = Braintree_Transaction::sale([
            'amount' => '25.00',
            'paymentMethodNonce' => $payment_method_nonce,
            'options' => [
              'submitForSettlement' => True
            ]
          ]);

        if ($result->success) {
            if ($result->transaction->id) {
                $braintreeCode = $result->transaction->id;
                echo "<pre>";
                print_r($braintreeCode);
                //updateUserOrder($braintreeCode, $session_user_id);
            }
        } else if ($result->transaction) {
            echo '{"OrderStatus": [{"status":"2"}]}';
        } else {
            print_r($result);
            echo '{"OrderStatus": [{"status":"0"}]}';
        }
    }
    ?>

```

【问题讨论】:

  • 你能解释为什么它被否决或者你只是喜欢投反对票吗?

标签: braintree


【解决方案1】:

全面披露:我在 Braintree 工作。如果您还有任何问题,请随时联系support

Braintree 客户端令牌和支付方式 nonce 是两个不同的元素。客户端令牌应该在您的服务器上生成并用于configure the JavaScript SDK 与令牌和您的 HTML 表单的 DOM ID;之后,您无需担心自己添加和填充隐藏字段。提交表单后,Braintree 创建一个付款方式 nonce,并通过隐藏输入将其与表单一起发送。

在服务器端,您的代码也需要稍作调整:您当前正在发送paymentMethodToken,它指的是现有支付方式的唯一标识符。 nonce 的键应该是paymentMethodNonce,如credit card guide 中所述。

$payment_method_nonce = $_POST['payment_method_nonce'];
$result  = Braintree_Transaction::sale([
    'amount' => '25.00',
    'paymentMethodNonce’ => $payment_method_nonce,
    'options' => [
      'submitForSettlement' => True
    ]
 ]);

【讨论】:

  • 嗯,我犯了一个愚蠢的错误,你说得对,我必须修改这里的代码是我更新的完整代码,我在更新我得到的代码后使用托管字段js errortype validation 和消息 User did not enter a payment method,当我尝试调查时,我发现在调用 braintree.setup() 后隐藏的输入没有填充到我的表单中,见上文我编辑了帖子并在下面添加了完整代码编辑部分,包括表单和服务器端处理。
  • 如托管字段integration example 中所述,“您需要定义&lt;div&gt; 容器来代替通常构成信用卡输入字段(卡号、到期时间)的&lt;input&gt; 元素日期和 CVV)。”看起来您的表单当前使用 &lt;input&gt; 元素。如果这不能解决您的问题,我建议您联系Braintree support
  • 是的,您提供 div 容器而不是输入元素是正确的,这就是问题所在,非常感谢您的回复
猜你喜欢
  • 2019-04-09
  • 2016-07-20
  • 2014-09-18
  • 2016-05-13
  • 2021-10-23
  • 2021-12-02
  • 2015-07-12
  • 2018-09-03
  • 2013-12-12
相关资源
最近更新 更多