条带:处理费用/客户错误,然后在PHP中将数据插入数据库

条带:处理费用/客户错误,然后在PHP中将数据插入数据库,php,stripe-payments,silex,Php,Stripe Payments,Silex,我在Silex和Stripe一起工作。在这里,我从表单中获取数据,然后创建$customer和$charge对象,然后将客户和订单信息保存到数据库中 我还想按照Stripe文档中的建议使用try/catch捕获所有可能的错误,但我觉得我的try/catch太长了。如果尝试成功,我想将数据插入数据库,但我不知道最佳做法是什么 这是我的密码: $app->post('/{category}/{id}', function ($id) use ($app) { $message = null;

我在Silex和Stripe一起工作。在这里,我从表单中获取数据,然后创建
$customer
$charge
对象,然后将客户和订单信息保存到数据库中

我还想按照Stripe文档中的建议使用try/catch捕获所有可能的错误,但我觉得我的try/catch太长了。如果尝试成功,我想将数据插入数据库,但我不知道最佳做法是什么

这是我的密码:

$app->post('/{category}/{id}', function ($id) use ($app) {

$message = null;

$book = $app['dao.book']->findById($id);

$minAmount = $book->getPrice();
$paidAmount = floatval($_POST['amount']);

// check if value matches
$convMinAmount = ($book->getPrice()) * 100;
$convPaidAmount = (floatval($_POST['amount'])) * 100;

if (($convMinAmount > $convPaidAmount)) {
    $message = 'Veuillez saisir un montant plus élevé que le montant minimum s\'il vous plait.';
} else {
    $item_bought = $book->getTitle();
    $token = $_POST['stripeToken'];
    $stripeinfo = \Stripe\Token::retrieve($token);
    $email = $stripeinfo->email;

    $customer = \Stripe\Customer::create(array(
        'email' => $email,
        'source' => $token
    ));

    try {
        $charge = \Stripe\Charge::create(array(
            'customer' => $customer->id,
            'amount' => $paidAmount * 100,
            'currency' => "eur",
            'description' => 'Achat d\'un livre',
            'receipt_email' => $customer->email
        ));

        // Prepare values for insert into DB
        $full_name = $charge->source->name;
        $address = $charge->source->address_line1 . ', ' . $charge->source->address_city .
            ' ' . $charge->source->address_zip . ', ' . $charge->source->address_country;

        // Save order to DB
        $commande = new Commande();

        $commande->setName($full_name);
        $commande->setAdress($address);
        $commande->setItemBought($item_bought);
        $commande->setPricePaid($paidAmount);
        $commande->setEmail($email);

        $app['dao.commande']->save($commande);

        $message = 'Merci pour votre achat. Votre commande d\'un montant de ' . (floatval($charge->amount)) / 100 . '€ est validée. Un mail récapitulatif vous a été envoyé.';

     } catch (\Stripe\Error\Card $e) {
        echo($e->getMessage());
        // Since it's a decline, \Stripe\Error\Card will be caught
        $body = $e->getJsonBody();
        $err = $body['error'];
        $message = $err;
    } catch (\Stripe\Error\RateLimit $e) {
        // Too many requests made to the API too quickly
        $message = 'Too many requests, veuillez réessayer plus tard s\'il vous plait.';
    } catch (\Stripe\Error\InvalidRequest $e) {
        // Invalid parameters were supplied to Stripe's API
        print('Status is: ' . $e->getHttpStatus() . "\n");
        $message = 'Les paramètres sont invalides, veuillez s\'il vous plait contacter le webmaster du site.';
    } catch (\Stripe\Error\Authentication $e) {
        // Authentication with Stripe's API failed
        // (maybe you changed API keys recently)
        $message = 'L\'authentication à l\'API Stripe a échoué, veuillez s\'il vous plait contacter le webmaster du site.';
    } catch (\Stripe\Error\ApiConnection $e) {
        // Network communication with Stripe failed
        $message = 'La communication a échoué, veuillez réessayer plus tard s\'il vous plait.';
    } catch (\Stripe\Error\Base $e) {
        // Display a very generic error to the user, and maybe send
        // yourself an email
        $message = 'Il semblerait que la requête ait échoué, veuillez réessayer plus tard s\'il vous plait';
    } catch (Exception $e) {
        // Something else happened, completely unrelated to Stripe
        $message = 'Il semblerait que la requête ait échoué, veuillez réessayer plus tard s\'il vous plait';
    }
}

return $app['twig']->render('book.html.twig', array(
    'book' => $book,
    'message' => $message,
    'minAmount' => $minAmount
));
最后,我返回一条处理任何案例的
$message
,并将用户重定向到book页面。
对不起,我在这里迷路了。代码正在运行,但我不确定这是最好的方法。谢谢你的帮助。

我从未使用过silex,但它应该与Symfony有很多共同之处。在symfony中,可以使用事件侦听器。您可以看到一些关于如何实现事件侦听器的示例

其思想是监听异常事件。检查异常是否来自条带,并根据需要设置消息。基本上,您只需将此代码移动到事件侦听器,这样就可以重用它而无需代码复制。然后,您可以修改示例,如下所示:

} catch (\Stripe\ErrorInterface $e) {
    $message = $e->getMessage();
} catch (SomeDbException $dbException){
    ...
}
假设所有条带错误异常实现相同的接口。(从未使用过条纹)

我不知道这是否是最佳实践,但它可以减少并清除代码

编辑 对不起,我误解了你的问题。说到你的观点。您应该保留它,因为它预期会有一些额外的数据库异常。如果将其放在try/catch块之后,即使出现异常,它也会将数据插入数据库

但最佳实践是将代码(持久化到db)提取到不同的服务中。此方法只负责获取请求并返回响应

因此,关于事件的第一点可以如下所示:

if (($convMinAmount > $convPaidAmount)) {
    $message = 'Veuillez saisir un montant plus élevé que le montant minimum s\'il vous plait.';
} else {
    $item_bought = $book->getTitle();
    try{
        $stripeService->makeRequest($_POST['stripeToken'],...)
        $databaseService->insertCommande($charge, $fulname, $address,...)


        $message = 'Merci pour votre achat. Votre commande d\'un montant de ' . (floatval($charge->amount)) / 100 . '€ est validée. Un mail récapitulatif vous a été envoyé.';

    } catch (\Stripe\ErrorInterface $e) {
        $message = $e->getMessage();
    } 
}

return $app['twig']->render('book.html.twig', array(
    'book' => $book,
    'message' => $message,
    'minAmount' => $minAmount
));

谢谢你的回复。事实上,我的异常都得到了处理(它们都来自Stripe yeah),不过我确实可以稍微清除一下代码。如果try部分有效,我更关心的是何时何地执行请求,而不是直接在try中执行请求。(或者我可以做一个方法来做这些事情,然后在尝试中调用它?)对不起,我错过了你的问题。现在答案更新了。好的,我考虑过这样的事情(委托给一个方法或最好的,一个服务),谢谢你让我走上正确的道路!我试试看。我将把你的回答记为已被接受。