2017-12-28 11 views
1

私はSilexのStripeで作業しています。ここで私のルートでは、フォームからデータを取得してから$customer$chargeというオブジェクトを作成したいのですが、顧客と注文情報をデータベースに保存します。ストライプ:手数料/顧客エラーが発生し、PHPのDBにデータを挿入します

ストライプのドキュメントで推奨されているように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を返し、私は本のページにユーザーをリダイレクトします。 ご質問には申し訳ありませんが、私はここで迷っています。コードは動作していますが、私はその最良の方法を確信していません。助けてくれてありがとう。

答えて

1

私はサイレックスを一度も使用していませんが、Symfonyとよく似ています。 symfonyでは、イベントリスナーを使用できます。 Hereには、イベントリスナーを実装する方法の例があります。

アイデアは例外イベントでリッスンすることです。例外がStripeからのものかどうかを確認し、必要なものに応じてメッセージを設定します。基本的には、このコードをイベントリスナーに移動するだけで、コードの重複なしに再利用できます。次に、例を次のように変更できます。

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

すべてのStripe Errors例外が同じインターフェイスを実装しているとします。 (決してストライプを使用しない)。

これがベストプラクティスかどうかわかりませんが、コードを減らしてクリアすることができます。

EDIT ご迷惑をおかけして申し訳ありません。あなたのところに。追加のデータベース例外が存在することが予想されるので、このままにしておく必要があります。 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 
)); 
+0

感謝を。実際に私の例外はすべて処理されています(彼らはすべてStripeのものです)。私の懸念事項は、try部分が有効である場合には、いつ試して直接実行するのではなく、いつ実行するかについてです。 (または、私はものをして試しに呼び出す方法を作ることができる?) – DevMoutarde

+0

申し訳ありませんがあなたの質問を逃した。これで答えが更新されました。 – user254319

+0

オク、私は正しい方法で私を入れてくれてありがとう、このようなことについて考えました(方法やベスト、サービスへの委任)。私はそれを試みます。私はあなたの答えを受け入れたものとしてマークします。 – DevMoutarde

関連する問題