2017-12-28 29 views
1

나는 Silex의 Stripe에서 일하고 있습니다. 여기, 내 경로에서 양식에서 데이터를 가져 오는 중 $customer$charge 개체를 만들고 싶습니다. 그런 다음 고객 및 주문 정보를 데이터베이스에 저장하려고합니다.스트라이프 : 수수료/고객 오류 처리 후 PHP의 DB에 데이터를 삽입하십시오.

스트라이프 (Stripe) 문서에서 권장하는대로 try/catch를 사용하여 가능한 모든 오류를 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

나는 silex를 사용한 적이 없지만 Symfony와 공통점이 많습니다. 심포니에서는 이벤트 리스너를 사용할 수 있습니다. Here 이벤트 리스너를 구현하는 방법에 대한 몇 가지 예를 볼 수 있습니다.

아이디어는 예외 이벤트에서 수신 대기하는 것입니다. 예외가 Stripe에 있는지 확인하고 필요한 것에 따라 메시지를 설정하십시오. 기본적으로이 코드를 이벤트 리스너로 이동하기 만하면 코드 중복없이 다시 사용할 수 있습니다.

} 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 
)); 
+0

감사를 회신합니다. 실제로 내 예외는 모두 처리됩니다. (모두 Stripe에서 가져옵니다.) 실제로 코드를 약간 지울 수는 있지만. 내 관심사는 try 부분이 유효한 경우 try에서 직접 실행하지 않고 요청을 실행할시기와 장소에 관한 것입니다. (또는 내가 물건을하고 그냥 시도에서 전화를하는 방법을 만들 수 있습니까?) – DevMoutarde

+0

죄송합니다 귀하의 질문을 놓쳤습니다. 이제 대답이 업데이트됩니다. – user254319

+0

오크, 나는 이런 식으로 생각했습니다 (방법이나 최선을 서비스에 위임했습니다). 올바른 방법으로 나를 보내 주셔서 감사합니다! 나는 그것을 시도 할 것이다. 당신의 대답을 받아 들일 것입니다. – DevMoutarde