使用Android

时间:2016-08-23 14:33:25

标签: php android token stripe-payments

里面有很多信息!

我知道有很多线程正在讨论这个问题,但是没有正确的答案,Stripe自己的教程和参考资料要好得多。所以希望我(以及其他人)可以最终看到这个长期存在的问题,为我们的业余爱好者开发。

我一直在努力实施Stripe的API超过两周,仍然遇到同样的问题。我的Android代码正常工作,直到我从Stripe接收我的令牌。

public class Checkout extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_checkout);
    }

    public void submitCard(View view) throws AuthenticationException {


        TextView cardNumberField = (TextView) findViewById(R.id.cardNumber);
        TextView monthField = (TextView) findViewById(R.id.month);
        TextView yearField = (TextView) findViewById(R.id.year);
        TextView cvcField = (TextView) findViewById(R.id.cvc);

        Card card = new Card(cardNumberField.getText().toString(), Integer.valueOf(monthField.getText().toString()), Integer.valueOf(yearField.getText().toString()), cvcField.getText().toString());
        //Card newCard = new Card("4242 4242 4242 4242", 12, 19, "123");

        Stripe stripe = new Stripe("pk_test_key");
        stripe.createToken(card, new TokenCallback() {
            @Override
            public void onError(Exception error) {
                //Error
                Toast.makeText(getApplicationContext(), error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onSuccess(Token token) {
                //send token to server
                Toast.makeText(getApplicationContext(), "Succesfully created a token", Toast.LENGTH_LONG).show();       // < this toast works, so my token is fine

                DatabaseTask databaseTask = new DatabaseTask("SENDTOKEN", token);
                databaseTask.execute();

            }
        });
    }

}

创建令牌后,我启动DatabaseTask,然后将该令牌发送到我的服务器(货币和金额在PHP脚本atm中被硬编码)。这个服务器有一个付费的SSL证书,我正在创建一个到我的PHP脚本的安全连接,它应该处理其余的。

public class DatabaseTask extends AsyncTask<String, Void, String> {

    String command = "";
    Token token;

    public DatabaseTask(String mCommand, Token mToken){
        command = mCommand;
        token = mToken;
    }

    @Override
    protected String doInBackground(String... strings) {

        String echoData = "";

        if (command.equals("SENDTOKEN")) {
            try {
                URL url = new URL("https://.../StripeConnection.php"); //there is a connection between the code and PHP script. This is tested.
                HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();


                StringBuilder builder = new StringBuilder();
                builder.append(URLEncoder.encode("stripeToken", "UTF-8"));
                builder.append("=");
                builder.append(URLEncoder.encode(token.toString(), "UTF-8"));
                String urlParameters = builder.toString();

                connection.setRequestMethod("POST");
                connection.setDoOutput(true);
                DataOutputStream dStream = new DataOutputStream(connection.getOutputStream());

                dStream.writeBytes(urlParameters);
                dStream.flush();
                dStream.close();

                BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line = "";
                StringBuilder responseOutput = new StringBuilder();

                while ((line = br.readLine()) != null) {
                    Log.e("DatabaseTask", line);
                    responseOutput.append(line);
                }
                br.close();

                echoData = responseOutput.toString();


            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return echoData;
    }

    protected void onPostExecute(String mData){
        Log.e("DatabaseTask", "onPostExecute result: " + mData);
    }

此DB任务的PHP脚本:

<?php

require_once('Stripe/init.php');

\Stripe\Stripe::setApiKey("sk_test_key");

$token = $_POST['stripeToken'];
$price = $_POST['price'];
$description = $_POST['description'];

// Create the charge on Stripe's servers - this will charge the user's card
try {
  $charge = Stripe\Charge::create(array(
    "amount" => 10000,          //"amount" => $price, in cents. //Hardcoded for testing
    "currency" => "cny",                        //Hardcoded for testing
    "source" => $token,                         //Hardcoded for testing
    "description" => "omschrijving" //"description" => $description //Hardcoded for testing
    ));

    echo "payment went succesfull";
} catch(\Stripe\Error\Card $e) {
  // The card has been declined
  echo "card was declined";
}

?>

在执行我的DatabaseTask和PHP脚本中的第一个ECHO之间,它似乎出错了,因为我从来没有得到任何回报,除了我的控制台中的一个巨大的ERROR消息。

08-23 16:04:28.083 20867-20867/... E/DatabaseTask: <br />
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: <b>Fatal error</b>:  Uncaught exception 'Stripe\Error\InvalidRequest' with message 'No such token: &lt;com.stripe.android.model.Token@... id=&gt; JSON: { from API request 'req_...'
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:   &quot;card&quot;: {
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;address_city&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;address_country&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;address_line1&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;address_line2&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;address_state&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;address_zip&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;country&quot;: &quot;US&quot;,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;currency&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;cvc&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;exp_month&quot;: 12,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;exp_year&quot;: 2019,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;fingerprint&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;last4&quot;: &quot;4242&quot;,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;name&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;number&quot;: null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:     &quot;type&quot;: null
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:   },
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:   &quot;created&quot;: &quot;Aug 23, 2016 16:04:25&quot;,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:   &quot;id&quot;: &quot;tok_...&quot;,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:   &quot;livemode&quot;: false,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask:   &quot;used&quot;: false
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: }' in /home/.../Stripe/lib/ApiRequestor.php:108
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: Stack trace:
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: #0 /home...Stripe/lib/ApiRequestor.php(227): Stripe\ApiRequestor-&gt;handleApiError('{\n  &quot;error&quot;: {\n...', 400, Array, Array)
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: #1 /home/.../Stripe/lib/ApiRequestor.php(65): Stripe\ApiRequestor-&gt;_interpretRe in <b>/home/.../Stripe/lib/ApiRequestor.php</b> on line <b>108</b><br />
08-23 16:04:28.093 20867-20867/... E/Checkout: <br /><b>Fatal error</b>:  Uncaught exception 'Stripe\Error\InvalidRequest' with message 'No such token: &lt;com.stripe.android.model.Token@... id=&gt; JSON: { from API request 'req_...'  &quot;card&quot;: {    &quot;address_city&quot;: null,    &quot;address_country&quot;: null,    &quot;address_line1&quot;: null,    &quot;address_line2&quot;: null,    &quot;address_state&quot;: null,    &quot;address_zip&quot;: null,    &quot;country&quot;: &quot;US&quot;,    &quot;currency&quot;: null,    &quot;cvc&quot;: null,    &quot;exp_month&quot;: 12,    &quot;exp_year&quot;: 2019,    &quot;fingerprint&quot;: null,    &quot;last4&quot;: &quot;4242&quot;,    &quot;name&quot;: null,    &quot;number&quot;: null,    &quot;type&quot;: null  },  &quot;created&quot;: &quot;Aug 23, 2016 16:04:25&quot;,  &quot;id&quot;: &quot;tok_...&quot;,  &quot;livemode&quot;: false,  &quot;used&quot;: false}' in /home/.../Stripe/lib/ApiRequestor.php:108Stack trace:#0 /home/.../Stripe/lib/ApiRequestor.php(227): Stripe\ApiRequestor-&gt;handleApiError('{\n  &quot;error&quot;: {\n...', 400, Array, Array)#1 /home/.../Stripe/lib/ApiRequestor.php(65): Stripe\ApiRequestor-&gt;_interpretRe in <b>/home/.../Stripe/lib/ApiRequestor.php</b> on line <b>108</b><br />

(链接,ID,令牌和其他个人内容被替换为......)

所以我已经尝试了几乎所有我能在网上找到的关于“没有这样的令牌:”的信息,但无济于事。

我检查了什么:   - 我的钥匙都没问题,这里没有错配   - 我的应用程序和我的PHP脚本之间有正确的连接   - 令牌已正确创建并由Stripe验证   - 我的服务器具有付费SSL证书,并与HttpsURLConnection建立了安全连接

我尝试了什么:   - 一遍又一遍刷新钥匙   - 在POST方法中将我的令牌作为字符串发送   - 尝试将我的令牌作为JSONtoken发送(从未让它工作)&gt; Passing Stripe tokens to server and handling on server   - 在asyncTask之外使用POST方法(读取它不需要)   - 反复阅读Stripe的整个文档&gt; https://stripe.com/docs/mobile/android   - 一遍又一遍地反复示例项目&gt; https://github.com/stripe/stripe-android/tree/master/example   - 搜索视频教程,但只找到了在网站上集成的教程   - 搜索在线课程,仅用于网络集成

所以现在我真的想知道Stripe对这个不可能完成的任务意味着什么:

  

在服务器上设置可以接收HTTP POST呼叫的端点   为了令牌。在onActivityResult方法(适用于Android Pay)或   onSuccess回调(使用自己的表单时),你需要POST   提供令牌到您的服务器。确保与您的任何沟通   服务器受SSL保护,以防止窃听。

如果您需要更多信息,请不要犹豫,因为这是完成我的第一次正确申请的最后一步。另外,请记住,过去3年我已经通过追踪和错误收集了所有的知识,尽管我知道很多事情,但我可能会错过一些基本知识。

感谢。

1 个答案:

答案 0 :(得分:3)

这里的错误是,您传递了从Stripe的SDK返回的整个令牌对象,而不是传递令牌ID tok_XXX。然后请求失败并显示错误

  

未捕获的异常&#39; Stripe \ Error \ InvalidRequest&#39;消息&#39;没有这样的标记:&lt; com.stripe.android.model.Token @ ... id =&gt; JSON:{来自API请求&#39; req _...&#39;

您需要更改代码以将令牌ID发送到PHP脚本,以解决问题。

builder.append(URLEncoder.encode(token.getId(), "UTF-8"));