🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Stripe

Stripeとは、米国のオンライン決済システム提供企業、及び同社が提供する決裁システムを指します。Webサイトやモバイルアプリにコードを組み込むことでクレジットカードなどの決済サービスが簡潔に追加できます。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

2964閲覧

【Stripe】複数のプランの中から一つを選択できるフォームを作りたい

emi3

総合スコア5

Stripe

Stripeとは、米国のオンライン決済システム提供企業、及び同社が提供する決裁システムを指します。Webサイトやモバイルアプリにコードを組み込むことでクレジットカードなどの決済サービスが簡潔に追加できます。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/10/11 05:58

編集2019/10/13 06:46

前提・実現したいこと

はじめて質問させていただきます、よろしくお願いいたします
普段はcssを触っていて、PHPを触るのは数年ぶりです
また、Stripeは初めて触ります
ので、もしかしたら考え方の前提が間違っているかもしれません
ご指摘いただけますと幸甚です

実現したいこと:
Stripeで、「単発」と「継続」の、それぞれにある複数のプランのうち、ひとつを選択して登録できるフォームを作りたい

発生している問題

Stripeの機能を実装するためにローカルで触っていますが、単純な構造から少しずつ変更し必要な部分を加えて作っていたところ、Stripeのダッシュボードでテストの売上が計上されなくなってしまいました

計上されていたのは「単発」と「継続」の二種類のみでテストしていたときです

動かなくなったのは、「単発」と「継続」の二種類の下に、複数のプランを下げて、選択肢を増やした後です

エラーメッセージ:ありません

該当のソースコード

html

1 <form action="charge.php" method="post" id="payment-form"> 2 <ul> 3 <li> 4  <label> 5     <select id="product" name="product" class="stripe-input"> 6      <option selected>▼決済コースを選択してください</option> 7       <optgroup label="継続"> 8        <option value="500_m">500円</option> 9        <option value="1000_m">1,000円</option> 10       </optgroup> 11       <optgroup label="単発"> 12        <option value="1000_s">1,000円</option> 13        <option value="5000_s">5,000円</option> 14       </optgroup> 15      </select> 16     </label> 17    </li> 18    <li><input type="email" name="email" class="email stripe-input" placeholder="Email"></li> 19    <li><input type="text" name="name" class="name stripe-input" placeholder="名前"></li> 20    <!-- Stripe Elements --> 21    <li><div id="card-number" class="stripe-input"></div></li> 22    <li><div id="card-expiry" class="stripe-input"></div></li> 23    <li><div id="card-cvc" class="stripe-input"></div></li> 24    <li><div id="stripe_err" role="alert"></div></li> 25    <li><button type="submit">ご購入手続き</button></li> 26   </ul> 27  </form>

js

1 2 var stripe = Stripe('pk_test_XXXXXX'); 3 4 var elements = stripe.elements(); 5 6 var style = { 7 base: { 8 color: '#000', 9 fontSize: '12px' 10 }, 11 invalid: { 12 color: '#000', 13 iconColor: '#000' 14 } 15 }; 16 17 const cardNumber = elements.create('cardNumber', {style: style,placeholder: 'カード番号 1111 1111 1111 1111'}); 18 cardNumber.mount('#card-number'); 19 const cardExpiry = elements.create('cardExpiry',{style: style,placeholder: '有効期限 MM/YY'}); 20 cardExpiry.mount('#card-expiry'); 21 const cardCvc = elements.create('cardCvc', {style: style,placeholder: 'セキュリティ番号'}); 22 cardCvc.mount('#card-cvc'); 23 24 cardNumber.addEventListener('change', function(event) { 25 var displayError = document.getElementById('stripe_err'); 26 if (event.error) { 27 displayError.textContent = event.error.message; 28 } else { 29 displayError.textContent = ''; 30 } 31 }); 32 33 var form = document.getElementById('payment-form'); 34 form.addEventListener('submit', function(event) { 35 event.preventDefault(); 36 stripe.createToken(cardNumber).then(function(result) { 37 if (result.error) { 38 var errorElement = document.getElementById('stripe_err'); 39 errorElement.textContent = result.error.message; 40 } else { 41 // Send the token to your server. 42 stripeTokenHandler(result.token); 43 } 44 }); 45 }); 46 47 function stripeTokenHandler(token) { 48 // Insert the token ID into the form so it gets submitted to the server 49 var form = document.getElementById('payment-form'); 50 var hiddenInput = document.createElement('input'); 51 hiddenInput.setAttribute('type', 'hidden'); 52 hiddenInput.setAttribute('name', 'stripeToken'); 53 hiddenInput.setAttribute('value', token.id); 54 form.appendChild(hiddenInput); 55 56 // Submit the form 57 form.submit(); 58 } 59

php

1<?php 2 3require __DIR__. '/vendor/autoload.php'; 4 5\Stripe\Stripe::setApiKey('sk_test_XXXXXX'); 6 7$token = $_POST['stripeToken']; 8$product = $_POST['product']; 9 10header('Location: thanks.html'); 11 12if($product == '1000_s'){ 13 14 try { 15 $responce = \Stripe\Charge::create(array( 16 "amount" => 1000, 17 "currency" => "jpy", 18 "source" => $token, 19 "description" => "単発1000円", 20 )); 21 }catch (\Stripe\Error\Card $e) { 22 23 console.log($e); 24 die('決済が完了しませんでした'); 25 } 26 27}elseif ($product == '5000_s') { 28 29 try { 30 $responce = \Stripe\Charge::create(array( 31 "amount" => 5000, 32 "currency" => "jpy", 33 "source" => $token, 34 "description" => "単発5000円", 35 )); 36 }catch (\Stripe\Error\Card $e) { 37 38 console.log($e); 39 die('決済が完了しませんでした'); 40 } 41 42}elseif ($product == '500_m') { 43 44 try{ 45 $customer = \Stripe\Customer::create(array( 46 'email' => $_POST['email'], 47 'source' => $token, 48 'metadata' =>['Name' =>$_POST['name']] 49 )); 50 51 }catch (\Stripe\Error\Card $e) { 52 console.log($e); 53 die('登録が完了しませんでした'); 54 } 55 56 try{ 57 $responce = \Stripe\Subscription::create([ 58 'customer' => $customer['id'], 59 'items' => [['plan' => 'plan_XXXXXX']], 60 ]); 61 62 }catch (\Stripe\Error\Card $e) { 63 console.log($e); 64 die('登録が完了しませんでした'); 65 } 66 67}elseif ($product == '1000_m') { 68 69 try{ 70 $customer = \Stripe\Customer::create(array( 71 'email' => $_POST['email'], 72 'source' => $token, 73 'metadata' =>['Name' =>$_POST['name']] 74 )); 75 76 }catch (\Stripe\Error\Card $e) { 77 console.log($e); 78 die('登録が完了しませんでした'); 79 } 80 81 try{ 82 $responce = \Stripe\Subscription::create([ 83 'customer' => $customer['id'], 84 'items' => [['plan' => 'plan_XXXXXX']], 85 ]); 86 87 }catch (\Stripe\Error\Card $e) { 88 console.log($e); 89 die('登録が完了しませんでした'); 90 } 91} 92

試したこと

  • ルートディレクトリを整理して、もう一度composer require stripe/stripe-phpをしました
  • プランIDを確かめてもう一度書き直しました
  • APIキーを確認し、書き換えました
  • 不必要なテストプランを削除しました

補足情報(FW/ツールのバージョンなど)

stripe/stripe-php (v7.3.1)
PHP 7.3.8

どうしたらよいか本気でわからず疲れ果ててここにたどり着きました
どうかお知恵をかしてください、よろしくお願いいたします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

8zca

2019/10/12 14:10

JSファイルが別にあり、そちらでcard-numberやcard-expiryにstripeエレメントをマウントされているとう前提でよいでしょうか。 であればマウントとstripeのトークンを取得しているJSファイルも質問文に追記していただいてよろしいでしょうか? また、PHPの途中に header('Location: thanks.html'); がありますがこれはPHPの最後に来るべきかと思われます。 console.logもPHPには定義されてないかと思います。
emi3

2019/10/13 01:26

コメントありがとうございます テスト環境のため、まだ別ファイルにはしておらず、html内に記載していました その部分を記載したいと思います PHPとconsole.logの件、ありがとうございます 急ぎ修正して、動くか試してみます ご指摘感謝します
emi3

2019/10/13 06:32

追記失礼致します console.logは問題なく削除できましたが、header('Location: thanks.html'); を移動したところ、Fatal error が出てしまいました 元に戻すと動作し、thanks.html に飛びます エラーメッセージ: Fatal error: Uncaught Error: Call to undefined function Stripe\HttpClient\curl_version() in C:\apache\httpd-2.4.41-win64-VS16\Apache24\htdocs\○○○\vendor\stripe\stripe-php\lib\HttpClient\CurlClient.php:78 Stack trace: #0 C:\apache\httpd-2.4.41-win64-VS16\Apache24\htdocs\○○○\stripe_practice_php\vendor\stripe\stripe-php\lib\HttpClient\CurlClient.php(66): Stripe\HttpClient\CurlClient->initUserAgentInfo() #1 C:\apache\httpd-2.4.41-win64-VS16\Apache24\htdocs\○○○\stripe_practice_php\vendor\stripe\stripe-php\lib\HttpClient\CurlClient.php(34): Stripe\HttpClient\CurlClient->__construct() #2 C:\apache\httpd-2.4.41-win64-VS16\Apache24\htdocs\○○○\stripe_practice_php\vendor\stripe\stripe-php\lib\ApiRequestor.php(459): Stripe\HttpClient\CurlClient::instance() #3 C:\apache\httpd-2.4.41-win64-VS16\Apache24\htdocs\○○○\stripe_practice_php\vendor\stripe\stripe-php\lib\ApiRequestor.php(319): Stripe\ApiRequestor->httpClient() #4 C:\apache\httpd-2.4.41-win64-VS16\Apache24\htdocs\○○○\stripe_practice_php\vendor\stripe\st in C:\apache\httpd-2.4.41-win64-VS16\Apache24\htdocs\○○○\stripe_practice_php\vendor\stripe\stripe-php\lib\HttpClient\CurlClient.php on line 78
emi3

2019/10/13 06:42

また、thanks.html に飛んだ後にStripe のダッシュボードを確認したところ、ログが「200 OK POST /v1/tokens」となってはいますが、イベントが生じていません そもそもPHPの書き方がおかしいのでしょうか 低レベルな質問で申し訳ありません どうか皆さまよろしくお願いいたします
guest

回答1

0

ベストアンサー

この事象ですが、header('Location: thanks.html') が先に来ることで

  1. 先に thanks.html にリダイレクトされて完了画面が表示
  2. stripe決済は引き続き行われるがfatal errorのため終了

している動きになっています。
そのため、基本的に(同期処理においては)すべてうまくいってからリダイレクトされるのをおすすめします。

エラーについては
Call to undefined function Stripe\HttpClient\curl_version
と出ていますのでcurlがインストールされていないように思われますね。
もしcurlのインストールがされてないようでしたらインストールをお願いします。

とはいえ、これまで売上がたっていたということなので少し謎ですがインストール済であればapacheやphpの設定は変更されたでしょうか?

投稿2019/10/14 02:38

8zca

総合スコア559

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

emi3

2019/10/14 07:01

まずは最初にありがとうございます ご指摘をうけて手当たり次第できることをやってみました 解決できましたので何をしたか書き起こします、オチで笑ってください まずはPATHが通っていないのかも、と思い、関係するすべての環境変数を上書きしました また、その際curlも再インストールしました 次に https://github.com/php-http/curl-client をみて ```composer require php-http/curl-client``` をしました そして https://michinobu.jp/tec/dialy/phpcurlcertificateproblem https://aulta.co.jp/2019/09/27/6919.html 上記を参考に 1921行目と1930行目を書き換えました そしてApacheを再起動しましたところ、そのときはじめて違うエラーが出ました ```(OS 10048)通常、各ソケット アドレスに対してプロトコル、ネットワーク アドレス、またはポートのどれか 1 つのみを使用できま す。 : AH00072: make_sock: could not bind to address [::]:8080``` 本当にすみません、他とぶつかるのが嫌で8080を聞きにいっていたのがだめだったようです 80に戻したところ、無事売り上げ計上されました 本当にしょうもないことではまって申し訳ありませんでした 自戒としてここに残します お世話になり本当に感謝致します
8zca

2019/10/14 10:04

解決されたようでよかったです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問