我创建了一个集成了 Stripe 以接受卡付款的 Android 移动应用程序。在我的 Android 应用程序中,我向我的 Laravel API 发送了一堆参数,其中一个是 Stripe 令牌。
10 次中有 9 次,我的服务器按预期处理。它将使用 Stripe-Cartalyst 创建一个收费对象并创建一个收费,假设没有抛出异常(例如错误的卡详细信息或服务器错误),然后我的 api 将继续处理支付成功并进行一些插入一个数据库,之后它将向客户端返回一个 201 HTTP 状态代码,然后我在 Android 端处理它。
我遇到的错误(或我做错的事情)是随机发生的。有时我的 API 会从 Stripe 抛出一个未捕获的异常,解释一个令牌(加密的 Stripe 卡详细信息),只能使用一次。我在 Android 端做了一些调试,可以验证我只在发送令牌的地方发出 1 个 HTTP 请求,并且在我的 Laravel API 上做了一些日志记录,并且发现了一些奇怪的事情。
我 在 API 上的发现,我将流程的一些关键时刻打印到了日志文件中。
- 打印令牌变量。
- 当进入try块创建charge对象时。
- 如果在 Android 应用上选择了“交付”(此处可能是毫无意义的日志)。
- 检查一些项目(这是从 Android 应用程序传递的数组。
- 在充电结束时,在将 201 返回给客户端之前,打印某种成功消息。
然后我开始重新创建错误,在大约 20/30 个订单之后它发生了,这是发生的过程:
首先,在 Android 应用程序上,发送了以下令牌(并打印到控制台);
tok_1DiK0uKIdjSiVG8mn8CV2iim
经过检查,这个HTTP请求只触发了一次,所以我认为不是Android问题。
接下来,在 API 日志文件中,发生了以下情况:
2018-12-17 11:11:56] local.DEBUG:令牌:tok_1DiK0uKIdjSiVG8mn8CV2iim [2018-12-17 11:11:56] local.DEBUG:创建 Stripe Charge
[2018-12-17 11:11:59] local.DEBUG:令牌:tok_1DiK0uKIdjSiVG8mn8CV2iim
[2018-12-17 11:11:59] local.DEBUG:创建 Stripe Charge
[2018-12-17 11:12:00] local.ERROR:目前有另一个正在进行的请求使用此 Stripe 令牌(这可能意味着您单击了两次,而其他费用仍在进行中):tok_1DiK0uKIdjSiVG8mn8CV2iim。如果该收费成功,则该令牌不能再次使用。{"exception":"[object] (Cartalyst\Stripe\Exception\MissingParameterException(code: 400): 当前有另一个正在进行的请求使用此 Stripe 令牌(这可能意味着您单击了两次,而另一个费用仍在进行中)通过):tok_1DiK0uKIdjSiVG8mn8CV2iim。如果收费成功,此令牌将无法再次使用。' at /home/rbfs6nkk73qi/api/prototype/vendor/cartalyst/stripe/src/Exception/Handler.php:123)[stacktrace]
[2018-12-17 11:12:00] local.DEBUG: 发货单
[2018-12-17 11:12:00] local.DEBUG:检查单项
[2018-12-17 11:12:00] local.DEBUG: Card delivery - Order through Android V0.5 app
这表明从我列出的 1-5 的步骤中,API 做了:1,2,1,2,error,3,4,5。
我完全不知道为什么我的 API 会随机运行两次。我在下面粘贴了我的 API 的相关部分,以查看我正在做的事情是否明显错误。感谢您对此的任何帮助。
我尝试过的最后一件事:我尝试在创建充电对象后直接将$token
变量设置为,这让我想知道这是否是一些.null
$stripe
Cartalyst bug
if($card) {
$token = $request->token; //Stripe token
Log::debug("Token: ".$token); //Step 1
try {
Log::debug("Creating Stripe Charge"); //Step 2
$stripe->charges()->create([
'currency' => $currency,
'amount' => $amount,
'source' => $token
]);
if(strcmp($delivery,"Delivery") == 0) {
Log::debug("Delivery order"); //Step 3
if($singleItems != null) {
Log::debug("Checking single items"); //Step 4
foreach($singleItems as $key => $value) {
$singleItem = DB::table('items')
->select('name','category','price')
->where('item_id', '=', $key)
->get();
foreach($singleItem as $item) {
DB::table('single_order_items')->insert(['order_number' => $id, 'item'=>$key, 'quantity'=>$value, 'name'=>$item->name, 'category'=>$item->category, 'price'=>$item->price]);
}
}
}
Log::debug("Card delivery - ".$description); //Step 5
return response("Order placed successfully", 201)
->header('Content-Type', 'text/plain');
}
} catch(\Cartalyst\Stripe\Exception\BadRequestException $e) {
//This exception will be thrown when the data sent through the request is mal formed.
$message = $e->getMessage();
Log::debug($message);
return response($message, 306)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\UnauthorizedException $e) {
//This exception will be thrown if your Stripe API Key is incorrect.
$message = $e->getMessage();
Log::debug($message);
return response($message, 307)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\InvalidRequestException $e) {
//This exception will be thrown whenever the request fails for some reason.
$message = $e->getMessage();
Log::debug($message);
return response($message, 308)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\NotFoundException $e) {
//This exception will be thrown whenever a request results on a 404.
$message = $e->getMessage();
Log::debug($message);
return response($message, 309)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\CardErrorException $e) {
//This exception will be thrown whenever the credit card is invalid.
$message = $e->getMessage();
Log::debug($message);
return response($message, 310)
->header('Content-Type', 'text/plain');
} catch(\Cartalyst\Stripe\Exception\ServerErrorException $e) {
//This exception will be thrown whenever Stripe does something wrong.
$message = $e->getMessage();
Log::debug($message);
return response($message, 311)
->header('Content-Type', 'text/plain');
}
}