里面有很多信息!
我知道有很多关于这个问题的线程,但是没有一个是正确的回答,Stripe自己的教程和参考也没有更好。所以希望我(和其他人)能够最终为我们这些业余开发者看到这个长期存在的问题。
我一直试图实现条纹的API超过2周现在,仍然停留在同样的问题。我的Android代码正常工作,直到我从Stripe收到我的Token。
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之间的某个地方出错了,因为我从来没有得到任何回报,除了在我的控制台中出现一个巨大的错误消息。
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: <com.stripe.android.model.Token@... id=> JSON: { from API request 'req_...'
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "card": {
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "address_city": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "address_country": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "address_line1": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "address_line2": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "address_state": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "address_zip": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "country": "US",
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "currency": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "cvc": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "exp_month": 12,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "exp_year": 2019,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "fingerprint": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "last4": "4242",
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "name": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "number": null,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "type": null
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: },
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "created": "Aug 23, 2016 16:04:25",
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "id": "tok_...",
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "livemode": false,
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: "used": 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->handleApiError('{'n "error": {'n...', 400, Array, Array)
08-23 16:04:28.083 20867-20867/... E/DatabaseTask: #1 /home/.../Stripe/lib/ApiRequestor.php(65): Stripe'ApiRequestor->_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: <com.stripe.android.model.Token@... id=> JSON: { from API request 'req_...' "card": { "address_city": null, "address_country": null, "address_line1": null, "address_line2": null, "address_state": null, "address_zip": null, "country": "US", "currency": null, "cvc": null, "exp_month": 12, "exp_year": 2019, "fingerprint": null, "last4": "4242", "name": null, "number": null, "type": null }, "created": "Aug 23, 2016 16:04:25", "id": "tok_...", "livemode": false, "used": false}' in /home/.../Stripe/lib/ApiRequestor.php:108Stack trace:#0 /home/.../Stripe/lib/ApiRequestor.php(227): Stripe'ApiRequestor->handleApiError('{'n "error": {'n...', 400, Array, Array)#1 /home/.../Stripe/lib/ApiRequestor.php(65): Stripe'ApiRequestor->_interpretRe in <b>/home/.../Stripe/lib/ApiRequestor.php</b> on line <b>108</b><br />
(链接,ID,令牌和其他个人物品被替换为…)
所以我已经尝试了几乎所有我能在网上找到的关于"No such Token:"的消息,但无济于事。
我检查了什么:-我的两把钥匙都没问题,没有错-我的应用程序和我的PHP脚本之间有一个适当的连接—token创建正确,并经过Stripe验证-我的服务器有一个付费的SSL证书,并与HttpsURLConnection建立了一个安全连接
我试过什么?-一遍又一遍地刷新按键-发送我的令牌作为一个字符串在POST方法-尝试将我的令牌作为JSONtoken发送(从未让它工作)>将条纹令牌传递到服务器并在服务器上处理-在asyncTask之外获取POST方法(读到它不需要)-重新阅读条纹的整个文档一遍又一遍> https://stripe.com/docs/mobile/android-一遍又一遍地分割示例项目> https://github.com/stripe/stripe-android/tree/master/example-搜索视频教程,但只在网站上找到整合教程-搜索在线课程,同样只搜索web集成
所以现在我真的想知道这个看似不可能完成的任务是什么意思:
在服务器上设置一个可以接收HTTP POST调用的端点对于令牌。在onActivityResult方法中(对于Android Pay)或onSuccess回调(当使用您自己的表单时),您需要POST向服务器提供令牌。确保与你的任何沟通服务器是SSL安全的,以防止窃听
如果你需要更多的信息,请不要犹豫,因为这是完成我的第一个适当的申请的最后一步。另外,请记住,我在过去的3年里积累了所有的知识,虽然我知道很多东西,但我可能会错过一些基本的知识。
谢谢。
这里的错误是,不是传递令牌id tok_XXX
,而是传递整个令牌对象,您从Stripe的SDK返回。然后请求失败,并报错
未捕获的异常'Stripe'Error'InvalidRequest'伴有消息'No such token: <com.stripe.android.model.Token@..。id>
你需要改变你的代码发送令牌id,而不是你的PHP脚本应该解决这个问题。
builder.append(URLEncoder.encode(token.getId(), "UTF-8"));