サーバー不要Gatsbyプロジェクトで商品を売る方法。stripeの決済機能実装。
Gatsbyjsで作ったサイトにStripeの決済機能を組み込み、ショッピングカート機能をつける
上のリンクの続きになります
dialogタグはhtml要素の上位に配置したいためgatsby-browser.jsに書き加える
import './src/style.css'
import 'prismjs/themes/prism.css'
import React from "react"
import { CartProvider } from 'use-shopping-cart'
export const wrapRootElement = ({ element }) => {
return (
<CartProvider
mode={"payment"}
cartMode={"client-only"}
stripe={process.env.GATSBY_STRIPE_PUBLISHABLE_KEY}
successUrl={'https://hi1t0.com/checkout-success'}
cancelUrl={'https://hi1t0.com/cart'}
currency={'jpy'}
>
<dialog id="add-to-cart" className={`add-to-cart`}>カートに入れました</dialog>
{element}
</CartProvider>
)
}
追加するボタンが押された時に、ダイアログを表示したいのでsrc/components/products/ProductCard.jsを編集する
handleAddItem
関数の中で、showModal関数実行でダイアログ表示させる
setTimeoutの中で1秒経ったらダイアログを非表示にしている
document.getElementById('add-to-cart').showModal()
...
setTimeout(() => {
document.getElementById('add-to-cart').close()
}, 1000)
...
import React, { useState } from "react"
import { useShoppingCart } from 'use-shopping-cart'
...
const ProductCard = ({ product }) => {
const [loading, setLoading] = useState(false)
const [priceId, setPriceId] = useState(product.prices[0]?.id)
const { checkoutSingleItem, addItem } = useShoppingCart()
const onChangePrice = event => {
setPriceId(event.target.value)
}
const handleAddItem = event => {
setLoading(true)
document.getElementById('add-to-cart').showModal()
// price_idからpriceオブジェクトをフィルターする
const priceIndex = product.prices.findIndex(p => p.id === priceId)
const item = product.prices[priceIndex]
addItem({price_id: item.id, price: item.unit_amount, currency: item.currency, name: product?.name,})
setTimeout(() => {
document.getElementById('add-to-cart').close()
setLoading(false)
}, 1000)
}
const handleSubmit = async event => {
...
}
return (
<div className="column is-6">
<form onSubmit={handleSubmit} className="has-text-centered">
<div style={cardStyles}>
{
product.images.length > 0 ?
<img src={product.images[0]} alt={product.name}/>
: ''
}
<fieldset style={cardMain}>
<legend style={legendStyles}>
<h4>{product.name}</h4>
<p>{product.description}</p>
</legend>
<label style={priceStyles}>
価格{" "}
<select name="priceSelect" style={selectBox} onChange={onChangePrice}>
{product.prices.map(price => (
<option key={price.id} value={price.id}>
{formatPrice(price.unit_amount, price.currency)}
</option>
))}
</select>
</label>
</fieldset>
<button
type="button"
onClick={(e) => handleAddItem(e)}
disabled={loading}
style={
loading
? { ...buttonStyles, ...buttonDisabledStyles }
: buttonStyles
}
>
追加する
</button>
<button
disabled={loading}
style={
loading
? { ...buttonStyles, ...buttonDisabledStyles }
: buttonStyles
}
>
今すぐ買う
</button>
</div>
</form>
</div>
)
}
export default ProductCard
ここで問題が、、、
safariで開いてみたら表示がおかしかった
iosのバージョンは15.2.1
調べてみると
ios15.4からdialogタグに対応しているらしい!
早速アップデートして確かめる
ちゃんとdialogタグが表示されるようになっています
めでたしめでたし