支払いプロバイダーとの統合。適切で堅牢なOOPアプローチ


8

歴史

現在、私たちはオンライン支払いにいわゆるリダイレクトモデルを使用しています(支払人を支払いゲートウェイに送信し、そこで彼は支払いの詳細を入力します-ゲートウェイは成功/失敗のコールバックページに戻ります)。これは簡単でわかりやすい方法ですが、残念ながら非常に不便であり、お客様を混乱させることがあります(サイトを離れる、別のサイトに追加ログインしてクレジットカードの詳細を変更するなど)。

意図と問題の説明

現在、XML要求と応答の交換を使用する統合アプローチに切り替える予定です。私の問題は、処理中に発生する可能性のあるすべて(またはほとんど)の要求にどのように対応するかです。通常、単純さは堅牢であり、複雑さは壊れやすいことを念頭に置いてください。

  • ユーザーによる中止:ユーザーはクレジットカードの詳細を入力し、送信を押します。プロバイダーのゲートウェイへのXMLメッセージが送信され、応答を待ちます。ユーザーがブラウザで「停止」を押すか、ウィンドウを閉じます。
    • PHPのignore_user_abort()はオプションかもしれませんが、それは信頼できますか?
    • ユーザーを「お待ちください」ページにリダイレクトすると、接続に依存しない実際のプロセッサへのAJAXまたはその他の要求が開かれます。
  • データベースがなくなる
    • 非常に複雑に聞こえますが、たとえば、米国のWebサーバーと英国のDBの場合、これは発生し、また発生します。ユーザーが注文を一緒にクリックすると、支払い要求がプロバイダーに送信されましたが、応答をデータベース。個々のステップに応じて、PHPを使用して「トランザクション」のようなSQLを開始し、最後にのみコミットまたはロールバックするアプローチを使用できますか?その後、コミットもロールバックも発生しなかった場合、ユーザーを「ロック」して、ユーザーが再度支払うことを防いだり、不適切に支払いを説明したりしないようにすることができます。
  • また、技術的に他に何を検討する必要がありますか?たとえば、Worldpay、Realex、SagePayの統合例では、洞察が得られません。また、私の検索エンジンまたは私の検索用語は、これについて他の誰かの考えを見つけるのに十分ではありませんでした。

これにどのように取り組むかについての洞察をありがとうございました!


1
Stripeを使用してください。頭痛を避けなさい。
sergserg 2012

Stripeを確認したところ、2.39%とトランザクションあたり30セントが課金されています。それは私に年間約12グランドを要します-私は0%と9ペンスのトランザクションを支払います...
ExternalUse

[これ]を読んでください。XMLベースを含むさまざまな支払いゲートウェイについての洞察が得られます。[1] [1]:vpasp.com/virtprog/vpasp_epsystems.htm
Badar

こんにちはBadarさん、残念ながら私の質問には答えられません。私は支払いゲートウェイがどのように機能するかを知っており、XML統合の選択は修正されています。私はそれを堅牢にする方法のベストプラクティスとヒントを探しています-おそらく私の質問は十分に具体的ではありませんか?
ExternalUse

回答:


8

支払いをほぼ独占的に扱っている開発者として、私はおそらく、起こりうる落とし穴がどこにあるのかについていくつかの指針を与えることができます。私は、トラフィックが高く、アクティブな決済サービスプロバイダー(PSP)が40を超え、1日あたり数万件のトランザクションを扱うサイトで働いています。そして、私を信じてください、sh * tは常にファンに当たります、そしてあなたができることはその時点からの状況に対処するために可能な限り準備することです。

記録、記録、さらに記録...

これは支払いプロセスの最も重要な部分です。必ずすべての記録を残してください。「この情報が100万回に1回の取引で私に役立ちますか?」答えが「はい」の場合は、ログに記録してください。

ロギングの主なポイントはデータベースです。開始、失敗、解決、リダイレクトなどのトランザクションはすべて、PSPごとにテーブルに保存されます。PSPがAPIを使用する場合、すべてのAPI呼び出しがログに記録されます(送信された要求と応答の両方)。すべてのコールバックもテーブルに記録されます。などなど。

予期しないイベントや例外が発生した場合は、トランザクションID、ユーザーIDなどに基づいて検索および簡単に見つけられるように、特定の形式でPHPログファイルに記録します。

あなたが例えば訴えられた場合、あなたはあなたがすべてのデータを持っていることに感謝するでしょう。

監視とアラート

何かがうまくいかないときに電子メールで警告するいくつかの簡単なテストで監視ロジックを組み込みます。たとえば、PSPで3つのコールバックが連続して失敗した場合。顧客があなたに気づかせた後で問題に対応するのではなく、問題にすばやく対応することができるこれらすべての小さなこと(常に発生するわけではありません)は非常に重要です。

データベーストランザクション

たとえば、データベーストランザクションをサポートするためにデータベース構造を設定または変更する余裕がある場合は、MySQLでInnoDBを使用します。コードでそれを処理する方法についてこの回答を見てください。トランザクションのすべてのステップが完了していること、または完了していないことを確認する必要があります。トランザクションが部分的に完了していることは、ユーザーとシステムの負担にすぎません。例:1)ユーザーがトランザクションを完了する、2)ユーザーが何らかの形で報酬を受け取る。ここでステップ1と2の両方が満たされていない場合は、トランザクションをステップ1で完了として設定しないでください。

連絡する技術者

技術的な問題がある場合は、技術担当者がすぐに連絡できるようにしてください。特にその人があなたと彼らの技術者との間で仲介することを決定する場合、アカウントマネージャーを持っていることはかなり役に立ちません。

私に起こった実世界の例:1つのPSPが突然機能を停止し、コードには何も変更がなく、何も変更していないと彼らは言っています。デバッグ情報を(アカウントマネージャーを介して)やり取りした後、技術者の1人がWSDLスキーマのフェッチがオフになっていることに気づきました。その後、WSDLスキーマを更新したことに気付き、いくつかのデバッグを行った後、PHPが古いWSDLスキーマをキャッシュしていることに気付きました。Skypeに技術担当者が直接連絡していた場合、これは解決されればすぐに検出された可能性があります。または、WSDLスキーマの変更を認めただけで、何かがうまくいかなかった場合にPSPから自白を得ることが難しい場合がよくあります。

最後の言葉...

あなたができるすべてを準備していることを前提と何かが起こることができます:)

これがまさにあなたが求めていた答えであったかどうかはわかりませんが、私は実際の支払いの例と、最大の罠や落とし穴を防ぐ方法を提供しようとしています。詳しく説明してほしいことがあれば、または別のトピックに興味があれば教えてください。


+1分散トランザクションの重要性について言及するのを忘れていました。PPと統合し、トランザクションを利用しないレガシーシステムを維持する必要があることは、悪夢のシナリオを直接目にしました。
maple_shaft

こんにちはオタクです、ありがとう-「ログ、ログ、さらにログ」の+1を受け取ります!私は今、この "送信"のアプローチを検討していました:ユーザーセッションのロック。保留中としてDBに支払いを挿入します。「自動決済」なしでリクエストを送信します(トランザクションの遅延)。成功した場合、支払いレコードを「送信済み」として更新します。PSPに「決済」コマンドを送信します。支払い記録を「完了」として更新し、ユーザーセッションのロックを解除します。(ロックとは、ユーザーのレコードにフラグを書き込むことを意味します。トランザクションが保留中にログインすると、「電話をかける」ページが表示されます。)文字数が足りなくなったので、それをコメントの答えにしていきます。
ExternalUse

1

正直なところ、Payment Gatewayを介してトランザクションを管理する最善の方法は、Webサービスを使用することです。多くの異なる支払いゲートウェイが、これらの種類のサービスを提供して、トランザクションごとの競争率の均一なパーセンテージと、顧客のクレジットカードにもかかる通常のクレジットカード手数料(Cyber​​sourceなど)を提供します。生活のほとんどすべてで、あなたはあなたが支払うものを手に入れます、9セント/トランザクションは、ユーザーをリダイレクトすることを強制しない評判の良い支払いプロセッサーでは存在しません。

トークン化と安全なデータ

システムにクレジットカードの詳細を保存すると問題が発生するだけで、住んでいる場所によっては、このデータの管理方法に対する法的要件や刑法が存在する場合もあります。Amazonでない限り、技術的および法的複雑さのすべてについて心配する必要はありません。支払い処理業者は、クレジットカードの詳細をサイトからサーバーに渡すことができるSSL暗号化Webサービスと、サーバーから支払い処理業者のWebサービスに渡してアカウントから支払いを送信できるようにすることで、このリスクと複雑さを取り除きます。プロセッサ。代わりに、Webサービスは、認証コード、またはシステムでトランザクションを一意に示すトークンを返し、特定のトランザクションのアカウントをすばやく検索するための参照番号を提供します。トークンをデータベースに保持することができます。トークンがシステムで危険にさらされている場合、ユーザーに実際の影響はありません。さらに、システムにクレジットカードの詳細をまったく保存しないことにより、システムが侵害された場合でも、ユーザーの銀行口座は安全です。

支払い記録の保持

決済代行業者と統合するこのアプローチには、決済代行業者の記録とは別に、トークンを介してリンクされている独自の決済記録および購入記録を維持できるという追加の利点があります。これにより、システム、分析クエリを通じて収益レポートを実行でき、ユーザーは実際に支払いプロセッサに情報を問い合わせることなく、購入を表示できます。

PCIコンプライアンス

評判の良い支払いプロセッサはすべてのシステムとデータをPCI準拠のサーバーと施設でホストします。PCIコンプライアンス自体の詳細と、それが重要である理由については、このサイトを参照してください

彼らが守らなければならない特定の要件があり、彼らのデータセンターは物理的にも技術的にも保護されなければなりません。ネットワークなどに暗号化されていないWAPを置くことはできません。これは実際には関係ありませんが、PCIコンプライアンスを主張するためにマーチャントシステムに期待される多くの要件があります。これらの要件には、次のものが含まれますが、これらに限定されません。

  • サイトを介した支払い要求でSSL暗号化を使用する。

  • いかなる状況においても、ログファイルやシリアル化されたオブジェクトなど、クレジットカード番号がシステムのどこかに保存されてはなりません。

  • 支払いプロセッサと通信するアプリケーションサーバーは、必要最小限の数のオープンポートのみを許可する適切に構成されたファイアウォールの背後にある必要があります。

  • 適切な技術担当者のみが、ネットワーク上のこれらのアプリケーションサーバーへの物理的またはリモートアクセスを許可されるべきです。

  • その他...

通常、ほとんどの決済処理業者は、ネットワーク上で実行し、PCI準拠になることで起こりうる問題を特定できるオンラインツールを提供します。ペイメントプロセッサを使用する必要はありませんが、ペイメントプロセッサは、サービスを利用し、PCIコンプライアンス基準を満たしていない場合、追加料金を請求する権利を留保します。


申し訳ありませんが、これは私の質問に回答または適用されません。WorldPayとRealex Paymentsの両方に(現時点では)評判の良い支払いプロセッサがあります。PCIコンプライアンスについての恒久的な監査があり、部分的なクレジットカードデータの社内保管に準拠していますが、定期的なストレージにはRealVaultとFuturePayを使用しています。私の質問は、私の質問で述べたことのベストプラクティスに関連しています。
ExternalUse

@ExternalUse支払いプロバイダーと適切に統合するためのベストプラクティスは何かを説明するのにかなり良い仕事をしたと感じました。SSLを使用し、ユーザーをリダイレクトせず、サーバー側からPPに安全なWebサービス呼び出しを行い、CCの詳細を保存せず、トークンで個別の支払い記録を維持し、設計でPCIコンプライアンスを検討します。私が良い仕事をしたと感じない場合は、おそらく他の誰かがあなたが探しているより正確な答えを出すことができます。
maple_shaft

1

以前の回答からのアイデアのおかげで、私が今持っている解決策を提案したいと思います。これが、ここにある循環器の知識からの1つまたは2つのコメントを招き、それを改善するのに役立つことを願っています。明確化のため:重要な問題ですが、私の質問は支払いサービスプロバイダー(PSP)、PCI DSS要件、または何かの法的意味合いを選択する方法を扱っていませんでした。 PSPを使用する「リダイレクト」モデル。

前提条件

顧客はクレジットカードの詳細をフォームに入力する段階にあります。私は彼が何を借りているのか、そして彼が提出したクレジットカードにどの金額と通貨を請求したいのかを知っています。

解決 (?)

  1. クレジットカードの詳細を含むフォームの送信時に、JavaScriptを使用して送信ボタンのデフォルトのアクションを停止します(JSまたはAJAXが使用できない場合は、エラーページに移動して、最新のものを取得するようにユーザーに通知できますブラウザ...)
  2. (タイマーで繰り返される)AJAX要求は、それ自体が別のファイルで実際の処理をトリガーするステータス更新スクリプトを呼び出します。「ignore_user_abort()を使用して、クライアントがブラウザまたは何かを閉じた場合
  3. そのため、AJAXは、たとえばメソッド-> StatusUpdate()を呼び出します-初めて呼び出された場合、プロセスを開始して「pleasewait」を返し、その後の呼び出しでセッション変数または何かを評価してステータスを更新します
  4. データベース内のユーザーのレコードを更新して、「lockSession」フラグを「locked」に設定します。ロックが解除される前に何かが発生した場合、ユーザーは、発生した混乱を整理するためにオフィスに連絡するように次回のログインで通知されます。 。
  5. 「準備済み」ステータスで支払いレコードをDBに挿入する
  6. 準備した支払いレコードの注文IDを使用して、リクエストをPSPに送信します。PSPによっては、遅延トランザクションとしてリクエストを送信できます(つまり、自動的に決済されません)。
  7. 準備されたレコードを新しいステータスで更新します(拒否された場合は、セッションのロックを解除して支払いページに戻ります。成功した場合は、ステータスが「送信済み」で更新されます)
  8. それが成功した場合、PSPからの認証参照やその他の重要な詳細情報がないため、取得した認証参照についてPSPに「決済」要求を送信します。
  9. 成功した場合は、支払いレコードを完了済みに更新します(または、私の場合は、PendingTransactionsからPaymentTransactionsに移動して更新します)。
  10. ユーザーのレコードから「ロック」フラグを削除します

その他の考慮事項

上記をあなたの知識とアイデアを共有するための招待として理解してください-それらは今のところただのアイデアです!

ロギング

ロギングに関するオタクに非常に同意します。現在、上記のプロセスのすべての段階で何らかの形式のファイルベースのロギングを使用することを検討しています(完全で検証されている場合でも、ログを数日間保持することを検討しています)。 ..)

データベーストランザクション

データベーストランザクションの使用に同意するかどうかはわかりません。私たちはMS SQLを使用しており、デフォルト設定では、接続が失われるとトランザクションがロールバックされます。また、トランザクションを自動コミットまたは自動ロールバックしないように設定すると、いくつかのオープンDBトランザクションが発生し、レコード/テーブルのロックなどに何らかの影響が生じる可能性があります。このプロセスでは、複数の更新を好むと思います。これらのいずれかが失敗した場合(およびその結果プロセスが終了した場合)、ユーザーは、手動で解決されるまで、完了した可能性のある(まだ記録されていない)トランザクションを再送信することはできません。

AJAX、政治

AJAXをサポートしないブラウザーを検討する必要があるかどうかは、完全にはわかりません。とにかくそれは「政治的」なトピックだと思います。私たちは私たちのビジネスに自由を受け入れる余裕があると思いますが、他の人はおそらくそうしないかもしれません。

AJAX、テクニカル

「StatusUpdate」メソッドを非同期で呼び出す私のアプローチについてはまだよくわかりません。最初の呼び出しで実際のプロセスをトリガーしようとします。しかし、良い例が見つからない場合は、これを別の質問にします。とにかく、あなたがベストプラクティスを知っている場合は、コメントで私(および他の人)に知らせてください。

最終的な考え

「最終」という言葉に少しでも近づく考えがあればいいのですが、これは私のために進行中の作業であり、フィードバックと、これをどのように改善できるかについてのさらなるヒントを求められている場合です。


あなたの解決策は健全に思えますが、実際には必要な行を楽観的レコードロックで分散トランザクションが同じことを達成できる場合、そのレベルの努力の必要性に疑問を投げかけます。MSSQLについてはわかりませんが、InnoDB MySQLでこれを行うことができれば、これが可能であると確信しています。トランザクションの使用に反対するあなたの主張に従うかどうかはわかりません。
maple_shaft

(間違って?)処理中にスクリプトが終了した場合、またはデータベースが(何らかの理由で)停止した場合にどうなるかについて心配しています。開始されたトランザクションはどうなりますか?コミット、ロールバック、または開いたままですか?そして、その質問は、セットアップとデータベースに応じて、a、b、またはcで答えられるかもしれません。開発をオープンソースのクラスセットとして共有することを検討していました。期待どおりに機能する場合は、コミュニティから知識を得たので、それに戻る必要があります。
ExternalUse

あなたはこれを少し考えすぎていると思います。何が起こっているかの記録を保持している限り、あなたはあなたが行くにつれて学ぶでしょう。 "そして、いいえ、いいえ、いいえ:)ログを永久に保存し、たとえば、日ごとに分割しますtrx_120917.log。ログは非常に小さく、ディスク容量は非常に安価です。とにかく、あなたのプロジェクトで頑張ってください!
Niklas Modes、2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.