読者コミュニティ|Next.jsとStripeではじめるシンプルなECサイト開発ワークショップ
本の感想や質問をお気軽にコメントしてください。
いつも有用な記事をありがとうございます。無事にECサイト作成できました!試しに、Netlifyのホスティングサービスを使用してデプロイしてみたいのですが、stripeAPIキーに関するエラーが発生します。本番環境へのデプロイは、stripeも本番環境に移行しないと出来ないのでしょうか?
ローカル環境ではなく、NetlifyやVercel, firebaseなどへアプリをデプロイする場合は、それぞれのサービスの環境変数にStripeのAPIキーを設定する必要があります。
設定方法については、各サービスのドキュメントにてEnvironment Variables
などで検索お願いします。
ありがとうございます!
税金の設定についてですが、
あらかじめ商品価格を税込価格で作成した場合、商品ページの「税率」タブから税率の設定も必要でしょうか?
また、Stripe Taxという自動で税金を設定してくれるサービスに関して、こちらの記事を拝見させていただきましたが、このサービスは有料という認識で間違いないでしょうか?このサービスを利用しない場合は、「設定」-> 「税金設定」->「税金の自動計算」をオフに設定すれば良いですか?
商品の料金を税込で設定している場合は、税率の設定やTaxの利用は必要ありません。
Stripe Taxは https://dashboard.stripe.com/tax で明示的に有効化しないと利用できない有料オプションです。ですので、ご自身で有効化操作をしていない場合は特に操作をする必要はありません。
ご回答ありがとうございます!
度々すみません…
zapierと連携させてWebhookイベントのメール送信を自動化したいのですが、こちらはstripeのテスト環境下では出来ない仕様に変更されたようなのですが、本番環境で、実際の支払いを行わずにシミュレーションするには、どのように進めたら良いでしょうか。
個人的なデモ作成では、pipedream( https://pipedream.com/ )を使っています。
ご回答ありがとうございます。pipedreamについて少しも知識がないので少し教えていただきたいのですが、pipedreamと zapierの違いとしてどのようなものがあるのでしょうか。pipedreamだと、stripeのテスト環境で使えるということでしょうか。
あまり詳しいわけではないのですが、基本的にはZapierと変わりがないものだと思います。
個人的に利用している理由は、
・無料プランで多少JavaScriptのコードが書けること
・Stripeのテストモードでも利用できること
の2点です。
ありがとうございます。
もし、stripeとpipedreamとの連携を紹介したstripeコミュニティ等の記事や動画がありましたら、ぜひ共有いただきたいです。とりあえず、私も触ってみます。ありがとうございます。
今の所、日本語の記事は見かけないですね・・・
公式のDocsをGoogle翻訳などかけながら試すことになるかと思います。
ありがとうございます。試してみます!
あと、何度もすみません…
サブスク契約で、契約の更新時にstripeカスタマーポータルのURLを顧客にメール送信することによって、取引の履歴や契約キャンセルや一時停止を受け付けたいと考えているのですが、カスタマーポータルURLの有効期間は何日ですか。有効期間はこちらで変更も可能ですか。もし可能でない場合、自社で顧客情報を管理するデータベースは持たない方向なのですが、顧客が自由に自身のカスタマーポータルページにアクセスする手段として何か方法はありますでしょうか。
カスタマーポータルは、APIでセッションを作成する場合、有効期限は非常に短く設定されており、変更もできません。
ノーコードの組み込み方法は、全ての顧客に同一URLが利用でき、有効期限はありません。
*ページアクセス時にStripe側が認証を行います。
ありがとうございます。
ノーコードの場合のログインリンク共有についてですが、これは、契約更新時の顧客へのメールに添付しておいても問題ないでしょうか。全ての顧客に同一URLとなっていますが、メール認証を経ることによって、顧客ごとに別々のポータルページを割り振っているという感じですか。
はい。
いくつかの注意点がありますので、詳細はドキュメントをご確認ください。
ありがとうございます。
本当に何度もすみませんが、、、
あと、サブスクプランの契約日の設定についてですが、契約スタート可能な曜日または日付をあらかじめ設定しておくことは可能ですか。契約スタート日が注文日とは必ずしも一致しない場合はどのようにしたらよいでしょうか。よろしくお願いいたします。
billing_cycle_anchor
を設定することで請求開始日を指定できます。
Subscription Schedule APIを利用して、初月のみクーポンを設定して割引のようなことも可能ではあります。
ワークショップ資料の内容から離れた内容になってきておりますので、
詳細等についてはサポートへご相談ください。
「04 Next.jsでAPIやサーバー側処理のあるサイトを作ってみよう」の最後の箇所で「npx next start -p 3100」を実行したところ、下記エラーが発生しました。どのようにすればエラーが回避できるでしょうか?
% npx next start -p 3100 [main]:+
ready - started server on 0.0.0.0:3100, url: http://localhost:3100
Error: Could not find a production build in the '/Users/hamez/_pj/nextjs-stripe-ec/.next' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id
at NextNodeServer.getBuildId (/Users/hamez/_pj/nextjs-stripe-ec/node_modules/next/dist/server/next-server.js:139:23)
at new Server (/Users/hamez/_pj/nextjs-stripe-ec/node_modules/next/dist/server/base-server.js:90:29)
at new NextNodeServer (/Users/hamez/_pj/nextjs-stripe-ec/node_modules/next/dist/server/next-server.js:86:9)
at NextServer.createServer (/Users/hamez/_pj/nextjs-stripe-ec/node_modules/next/dist/server/next.js:109:16)
at async /Users/hamez/_pj/nextjs-stripe-ec/node_modules/next/dist/server/next.js:121:31
Error: Could not find a production build in ~'.next' directory.
については、npx next build
を実行してから再実行することで解決できます。
ありがとうございます!「npx next build」でエラー無くなりました。
06 の 「jqを利用して整形した実行結果の例」で、
curl http://localhost:3000/api/products | jq .
を実行したのですが、
zsh: command not found: jq
が帰ってきて商品一覧が表示されません。
すみません。jqありきの説明が途中で混ざっていますね・・・
curl http://localhost:3000/api/products で文字列が大量に表示されれば、動作確認としてはOKです。
macの場合は、brew install jqでインストールできます。
06の下記コマンドを実行したところ、下記エラーになりました。
% curl http://localhost:3000/api/products [main]:+
wait - compiling /api/products...
wait - compiling...
event - compiled client and server successfully in 110 ms (426 modules)
error - Error: You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/.
wait - compiling /_error (client and server)...
wait - compiling...
event - compiled client and server successfully in 87 ms (427 modules)
<!DOCTYPE html><html><head><style data-next-hide-fouc="true">body{display:none}</style><noscript data-next-hide-fouc="true"><style>body{display:block}</style></noscript><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills.js?ts=1650607714161"></script><script src="/_next/static/chunks/webpack.js?ts=1650607714161" defer=""></script><script src="/_next/static/chunks/main.js?ts=1650607714161" defer=""></script><script src="/_next/static/chunks/pages/_app.js?ts=1650607714161" defer=""></script><script src="/_next/static/chunks/pages/_error.js?ts=1650607714161" defer=""></script><script src="/_next/static/development/_buildManifest.js?ts=1650607714161" defer=""></script><script src="/_next/static/development/_ssgManifest.js?ts=1650607714161" defer=""></script><script src="/_next/static/development/_middlewareManifest.js?ts=1650607714161" defer=""></script><noscript id="__next_css__DO_NOT_USE__"></noscript></head><body><div id="__next"></div><script src="/_next/static/chunks/react-refresh.js?ts=1650607714161"></script><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":500}},"page":"/_error","query":{"__NEXT_PAGE":"/api/products"},"buildId":"development","isFallback":false,"err":{"name":"Error","message":"You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/.","stack":"Error: You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/.\n at res.toJSON.then.StripeAPIError.message (/Users/hamez/_pj/nextjs-stripe-ec/node_modules/stripe/lib/StripeResource.js:214:23)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"gip":true,"scriptLoader":[]}</script></body></html>%
.env.local ファイルの作成場所等に問題がありますか。
% ls nextjs-stripe-ec/.env.local
nextjs-stripe-ec/.env.local
環境変数をNext.jsが読み込めていない様子ですので、一度npx next dev
を停止して再実行していただけますでしょうか?
「npx next start」が起動していたので、そちらを停止/再実行しましたが、同様のエラーが出力されているようです。
% jobs
[1] - running npm run dev
[2] + running npx next start -p 3100
# 上記「npx next start -p 3100」を停止
% npx next start -p 3100 &
[2] 12757
% curl http://localhost:3000/api/products
error - Error: You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/.
<!DOCTYPE html><html><head><style data-next-hide-fouc="true">body{display:none}</style><noscript data-next-hide-fouc="true"><style>body{display:block}</style></noscript><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills.js?ts=1650608864866"></script><script src="/_next/static/chunks/webpack.js?ts=1650608864866" defer=""></script><script src="/_next/static/chunks/main.js?ts=1650608864866" defer=""></script><script src="/_next/static/chunks/pages/_app.js?ts=1650608864866" defer=""></script><script src="/_next/static/chunks/pages/_error.js?ts=1650608864866" defer=""></script><script src="/_next/static/development/_buildManifest.js?ts=1650608864866" defer=""></script><script src="/_next/static/development/_ssgManifest.js?ts=1650608864866" defer=""></script><script src="/_next/static/development/_middlewareManifest.js?ts=1650608864866" defer=""></script><noscript id="__next_css__DO_NOT_USE__"></noscript></head><body><div id="__next"></div><script src="/_next/static/chunks/react-refresh.js?ts=1650608864866"></script><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":500}},"page":"/_error","query":{"__NEXT_PAGE":"/api/products"},"buildId":"development","isFallback":false,"err":{"name":"Error","message":"You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/.","stack":"Error: You did not provide an API key. You need to provide your API key in the Authorization header, using Bearer auth (e.g. 'Authorization: Bearer YOUR_SECRET_KEY'). See https://stripe.com/docs/api#authentication for details, or we can help at https://support.stripe.com/.\n at res.toJSON.then.StripeAPIError.message (/Users/hamez/_pj/nextjs-stripe-ec/node_modules/stripe/lib/StripeResource.js:214:23)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)"},"gip":true,"scriptLoader":[]}</script></body></html>%
http://localhost:3000/ はnpm run dev
のほうを再実行させないとです。
npx next start -p 3100
でスタートしているアプリは、http://localhost:3100/ ですね。
また、npx next start
の方に更新を反映させるためには、npx next build
も実行する必要があります、
09 の「APIをアプリに組み込もう」で
<form action="/api/checkout_session" method="POST">
<input type='hidden' name='price' value={price.id}/>
<input type='hidden' name='quantity' value={1}/>
<Button type='submit'>いますぐ注文する</Button>
</form>
に書き換えたところ
「今すぐ注文する」のボタンを押すと
に遷移し下記のように表示されてしまいます。
{"id":"cs_test_a1VepRRes1oytOVe7gv5kFO2s8Z3RCEgGhdItCwLSX5YqrBqsCyRWatVwc","object":"checkout.session","after_expiration":null,"allow_promotion_codes":null,"amount_subtotal":100,"amount_total":100,"automatic_tax":{"enabled":false,"status":null},"billing_address_collection":null,"cancel_url":"http://localhost:3000/","client_reference_id":null,"consent":null,"consent_collection":null,"currency":"jpy","customer":null,"customer_creation":"always","customer_details":null,"customer_email":null,"expires_at":1650696338,"livemode":false,"locale":null,"metadata":{},"mode":"payment","payment_intent":"pi_3KrGFLLfNcyBUaEb26Nfz19I","payment_link":null,"payment_method_options":{},"payment_method_types":["card"],"payment_status":"unpaid","phone_number_collection":{"enabled":false},"recovered_from":null,"setup_intent":null,"shipping":null,"shipping_address_collection":null,"shipping_options":[],"shipping_rate":null,"status":"open","submit_type":null,"subscription":null,"success_url":"http://localhost:3000/success","total_details":{"amount_discount":0,"amount_shipping":0,"amount_tax":0},"url":"https://checkout.stripe.com/pay/cs_test_a1VepRRes1oytOVe7gv5kFO2s8Z3RCEgGhdItCwLSX5YqrBqsCyRWatVwc#fidkdWxOYHwnPyd1blpxYHZxWjA0TndAYVdJY0tmfEdQZEBnMV9nMn8wTGxtcElxc3BRYzdpMHE0cW53aHNRMDE9MTVPSlFTU3NAZFw2Uk1tUH9kNV1VTjRuSXFNVmMwdkZMNFNwPEhNUjNWNTVCTUY0VTZOUScpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl"}
「作成した決済ページにリダイレクトしよう」ステップのコード変更が保存できていないかもしれません。
データがそのまま表示されるのは、res.status(200).json(session)
が実行されているからの可能性が高いです。
res.redirect(301, session.url)
で保存できていればリダイレクトしますので、一度確認をお願いします。
自分も同じところで躓いてましたが、「権限」が一箇所間違って設定していました。
そこを変更したらうまく行きました。
貴重な情報ありがとうございます!
全て実装してSafariやiPhoneのGoogleで会計(checkout_session)に移るとポップアップのブロックで決済画面に遷移できません。こちら対策はございますか👀??
Google Payでの決済処理がうまくいかない・・・という理解で良いでしょうか?
「Checkoutページの表示がうまくいかない」ケースについてですと、
window.open(session.url)
の処理がブロッカーに止められているのかなと思います。
この挙動自体はブラウザの仕様によるものですので、ユーザー側で許可していただく必要があります。
回避する方法としては、Next.jsのuseRouter
を使って、同じウィンドウ内で遷移させればよいと思います。
認識のとおりです。ご回答ありがとうございます!
userouterで対策できました!
すみません、追加で。。
cart_sessionで決済終了後、successページに遷移するかと思いますが、
カートの中身がリセットされていません。
こちらの対策をご教示頂けますか??
(今は暫定的にカード情報等を入力する画面に遷移する時にclearCart()しています!
注文完了後の後処理についてが、本資料には抜けていますね・・・
後ほど章の追加をしますので、詳細については少々お待ちください。
簡単に流れを書きますと、以下の通りです。
・Next.jsで注文完了用ページを用意(page/thanks.tsx
など)
・<CartProvider />
のsuccessUrl
に作成したthanksページのURLを指定
・注文完了ページにて、useEffect
を使ってclearCart()
を実行
リダイレクト前にクリアしますと、カゴ落ち時にカートデータが復元できなくなります。
そのため、注文完了ページ側で処理することをお勧めします。
注意点
コンビニ決済・銀行振込をサポートする場合、リダイレクトされないためにこの動きは利用できません。
もしコンビニ決済・銀行振込を利用する場合は、今暫定対応として実装されている「リダイレクト前にクリアする」での対応となります。
ご丁寧に回答頂きありがとうございます。
確かに、successUrlでclearCart()しなければなりませんね!
コンビニ・銀行振り込みについても承知いたしました!
すみません、下記についてご教示願いたいです。
・併せて、決済完了後に商品を非表示するにはどうすればよいか。
アーカイブをAPI側で操作(active: false)ですればよいとドキュメントにありましたがうまく行かず、ご教示頂きたいです。
よろしくお願いします。
うまくいかなかったケースですが、どのようなエラーが画面またはログに表示されていますでしょうか?
お返事頂きありがとうございます。
checkout_sessionを呼び出す際に下記のエラーが発生しております。
error - unhandledRejection: Error: The provided key 'rk_test_*********************************************************************************************3x3N4t' does not have the required permissions for this endpoint on account 'acct_1LgMwAGdTYrk9Kye'. Having the 'rak_product_write' permission would allow this request to continue.
api/checkout_session.js(一部抜粋)
const stripe = new Stripe(process.env.STRIPE_API_KEY, {
apiVersion: '2022-08-01',
maxNetworkRetries: 3,
});
const session = await stripe.checkout.sessions.create({
mode: 'payment',
line_items: lineItems,
success_url: `${process.env.NEXT_PUBLIC_BASE_URL}/success`,
cancel_url: `${process.env.NEXT_PUBLIC_BASE_URL}`,
billing_address_collection: 'required',
});
items.map(async (item) => {
await stripe.products.update(item.id, { active: false });
});
共有ありがとうございます。
APIエラーについてですが、制限付きキーに「productの書き込み権限」が付与されていないことが原因です。
ワークショップ資料では、必要最低限の権限のみ設定しておりますので、追加でAPI操作を行いたい場合は、そのリソースの書き込み・読み込み権限が有効になっているかの確認をお願いします。
設定を変更することで解決できました。
(エラー文に解決策書いてましたね、すみません)。
ありがとうございました!
いつもご対応頂きありがとうございます。
クレジット決済後に商品を表示させないようにしたいのですが、決済が完了した後のアクションはどこに記載していけばよろしいのでしょうか。
Webhookを利用して、商品または価格を変更しましょう。
仕組みとしては、こちらの記事が参考になるかと思います。
Webhookについてはこちらをご確認ください。