180112 nishimoto-stripes-v1

15
アクセシブルな決済サイトの試作 with Stripe + Python + NVDA 西本 卓也 [email protected] / @24motz 2018-01-12 1

Transcript of 180112 nishimoto-stripes-v1

アクセシブルな決済サイトの試作with Stripe + Python + NVDA

西本 卓也 [email protected] / @24motz

2018-01-12

1

pcn-hiroshima.connpass.com

2

第3回 1月27日(土曜)会場 fabbit広島駅前

すごい広島 with Python

• 2017年4月から毎月の最後の水曜日の夜に開催• 2017年3月 Python Boot Camp in 広島

• 2016年 / 2015年は PyCon mini Hiroshima を開催

• Python に興味がある人が集まって情報交換

• Slack PyConJP Fellow #hiroshima• http://pyconjp-fellow.herokuapp.com/

•今年は PyCon mini Hiroshima をやりたい

3

NVDA / NVDA日本語チーム

4

アクセシブルな決済サイト

•要求• スクリーンリーダー利用者がちゃんと使える

•具体的には• iOS : Safari + VoiceOver

• Windows : Firefox + NVDA

•特定の環境向けのワークアラウンドはしない• アクセシビリティの Web 標準に準拠

5

決済プラットフォームの評価

•テストモード• ユーザー環境と同じ条件の検証が不可欠

• 決済を実行してみないと試せない、では困る

• UIやライブラリの検証• サイトに簡単に組み込める=問題があっても自力で直せない

• 最初はよかったのに突然悪くなることもあり得る• 外部ライブラリを動的に読み込んでいる場合

• 場合によってはあきらめて自前で作る

6

Stripe Checkout

• https://stripe.com/docs/checkout/tutorial

7

Python + Flask

8

Tabキーでフォーカス移動すると

•モーダルダイアログの外にも行ける(実行もできる)

•ダイアログのクローズにフォーカスを移動できない

9

決済情報を保存する

10

コーディングWebアクセシビリティ

• 6-3「ダイアログ」注意点

• モーダルダイアログが開いている間はその他の要素を操作させない

• ブラウザのアドレスバーなどにフォーカスを移動できるように

• ダイアログを閉じるときに、そのダイアログを呼び出した要素にフォーカスを戻す

11

Stripe Elements (v3)

• https://stripe.com/docs/stripe-js

• https://stripe.com/elements

12

試作サイト

• https://stripe.com/docs/stripe-js/elements/quickstart

13

<form action="/pay" method="post" id="payment-form"><div class="form-row">

<label for="card-element">クレジットカード情報を入力してください</label><div id="card-element"></div><div id="card-errors" role="alert"></div>

</div><button type="submit">送信する</button><input type="hidden" name="stripeToken" id="stripeToken" value="" />

</form>

クライアント / サーバーサイド

14

var form = document.getElementById('payment-form');form.addEventListener('submit', function(event) {

event.preventDefault();stripe.createToken(card).then(function(result) {if (result.error) {

// handle error} else {

document.getElementById('stripeToken').value = result.token.id;form.submit();

}});

});

@app.route('/pay', methods=['POST'])def pay():

# handle login / logout / emailstripeToken = request.form['stripeToken']amount = 1000customer = stripe.Customer.create(

email=email,source=stripeToken

)charge = stripe.Charge.create(

customer=customer.id,amount=amount,currency='jpy',description='Flask Charge'

)return render_template('pay.html', ...)

まとめ

• Stripe looks good to me

• TODO• VoiceOver 検証

15