Upgrade to Pro — share decks privately, control downloads, hide ads and more …

モバイル決済アプリの作り方 / How to develop a mobile payment...

Avatar for kenmaz kenmaz
September 07, 2019

モバイル決済アプリの作り方 / How to develop a mobile payment app

iOSDC2019の発表資料です。
https://fortee.jp/iosdc-japan-2019/proposal/8cec3433-83bd-48cd-a13d-6742430518d2

動画はこちら
https://www.youtube.com/watch?v=Q182EngkH_0

近年、モバイル決済アプリが非常に話題になっています。
このトークではそんなモバイル決済アプリの開発現場から、様々な技術的トピックについてiOSアプリ開発者視点からみなさんに共有します。
モバイル決済アプリ開発特有のトピック、例えば
- Apple Pay In-App Provisionig を用いたiD決済の仕組み
- QRコードによるコード決済の仕組み
- 銀行口座接続や顔認証+公的証明書による本人確認手法技術について
- 既存の巨大なアプリに対して、いかに安全・効率的にモバイル決済機能を追加するか
- お金を扱うアプリとしてのセキュリティの重要性とその実現方法
- モバイル決済アプリ開発の今後
などについてお話します。

Avatar for kenmaz

kenmaz

September 07, 2019
Tweet

More Decks by kenmaz

Other Decks in Technology

Transcript

  1. ۜߦޱ࠲νϟʔδ ίϯϏχ"5. νϟʔδ ΫϨδοτΧʔυ ݸਓؒૹۚ ϑϦϚΞϓϦച্ۚ "QQMF1BZ ίʔυܾࡁ ωοτܾࡁ ݸਓؒૹۚ

    ۜߦޱ࠲ৼࠐ 8BMMFU $BTI*O $BTI0VU લ෷ࣜࢧ෷͍खஈൃߦۀ ϙΠϯτ IUUQTXXXTLFTTBJKQJOGPMBXIUNM
  2. "QQMF1BZ ίʔυܾࡁ ωοτܾࡁ ݸਓؒૹۚ ۜߦޱ࠲ৼࠐ 8BMMFU $BTI*O $BTI0VU ۜߦޱ࠲νϟʔδ ίϯϏχ"5.

    νϟʔδ ΫϨδοτΧʔυ ݸਓؒૹۚ ϑϦϚΞϓϦച্ۚ ऩೲ୅ߦۀ ˞ٞ࿦͋Γ ˞஫ IUUQTTUPSJBMBXKQCMPH
  3. "QQMF1BZ ίʔυܾࡁ ωοτܾࡁ ݸਓؒૹۚ ۜߦޱ࠲ৼࠐ 8BMMFU $BTI*O $BTI0VU ۜߦޱ࠲νϟʔδ ίϯϏχ"5.

    νϟʔδ ΫϨδοτΧʔυ ݸਓؒૹۚ ϑϦϚΞϓϦച্ۚ ࢿۚҠಈۀ IUUQTXXXTLFTTBJKQJOGPMBXIUNM
  4. ࢿۚҠಈۀ d w ۜߦ౳Ҏ֎ͷऀ͕ҝସऔҾΛۀͱͯ͠ӦΉ΋ͷ w ಺ֳ૯ཧେਉͷొ࿥͕ඞཁ w ̍ճ͋ͨΓͷૹֹۚສԁҎԼ w ߴ౓ͳ૊৫੔උ

    w ࡒ੓ج൫੔උ w ൜ࡑऩӹҠస๷ࢭ๏ͷن੍Λड͚Δ ࢿܾۚࡁ๏ୈࡾेࣣ৚ IUUQTFMBXTFHPWHPKQTFBSDIFMBXT4FBSDIFMBXT@TFBSDIMTHEFUBJM MBX*E"$
  5. ൜ࡑऩӹҠస๷ࢭ๏ w ൜ࡑऩӹͷҠసʢʹϚωʔϩϯμϦϯάʣͳ ͲΛ๷ࢭ͢ΔͨΊͷ๏཯ w औҾ࣌֬ೝٛ຿ w औҾ࣌ʹຊਓ֬ೝ ,:$ ͕ඞཁ

    w Ͳ͏΍ͬͯʁ ൜ࡑʹΑΔऩӹͷҠస๷ࢭʹؔ͢Δ๏཯ୈ࢛৚ IUUQTFMBXTFHPWHPKQTFBSDIFMBXT4FBSDIFMBXT@TFBSDIMTHEFUBJM MBX*E"$ ,:$,OPX:PVS$VTUPNFS
  6. "QQMF1BZ ίʔυܾࡁ ωοτܾࡁ ݸਓؒૹۚ ۜߦޱ࠲ৼࠐ 8BMMFU $BTI*O $BTI0VU ۜߦޱ࠲νϟʔδ ίϯϏχ"5.νϟʔδ

    ΫϨδοτΧʔυ ݸਓؒૹۚ ϑϦϚΞϓϦച্ۚ ຊਓ֬ೝ ,:$ ϞόΠϧܾࡁΞϓϦͷߏ੒ཁૉ
  7. J04 %FWJDF "QQMF τʔΫϯ ϓϩόΠμʔ wΧʔυ໊ٛ wΧʔυ൪߸ '1"/  wηΩϡϦςΟίʔυ

    %1"/ 4FDVSF &MFNFOU IUUQTTVQQPSUBQQMFDPNKBKQ)5 "QQMF1BZͷΧʔυొ࿥ϑϩʔ '1"/ˠ%1"/ ੜͷΧʔυ൪߸ͱ͸ผͷΧʔυ ൪߸ʢ%1"/τʔΫϯʣʹม׵
  8. J04 %FWJDF ͓ళ τʔΫϯ ϓϩόΠμʔ "VUI ✅ %1"/ 4FDVSF &MFNFOU

    Χʔυ ձࣾ "QQMF1BZͷܾࡁϑϩʔ %1"/ˠ'1"/ '1"/ J04σόΠεʙτʔΫϯϓϩόΠμʔؒͰ ੜͷΧʔυ൪߸ '1"/ Λྲྀͣ͞ʹܾࡁՄೳ
  9. 1BTT,JU w Χʔυొ࿥ॲཧ w 1,"EE1BZNFOU1BTT7JFX$POUSPMMFS w 1,"EE1BZNFOU1BTT3FRVFTU w ొ࿥ঢ়ଶɾ୺຤ରԠঢ়گͷνΣοΫ w

    1,1BTT-JCSBSZ1,1BZNFOU1BTT ˞DPNBQQMFEFWFMPQFSQBZNFOUQBTTQSPWJTJPOJOH&OUJUMFNFOU͕ඞཁ IUUQTEFWFMPQFSBQQMFDPNEPDVNFOUBUJPOQBTTLJU IUUQTEFWFMPQFSBQQMFDPNMJCSBSZBSDIJWFEPDVNFOUBUJPO.JTDFMMBOFPVT3FGFSFODF&OUJUMFNFOU,FZ3FGFSFODF "QQMF1BZBOE1BTT,JU&OUJUMFNFOUT"QQMF1BZBOE1BTT,JU&OUJUMFNFOUTIUNMBQQMF@SFGEPDVJE51$)48
  10. +123 w ΩϟογϡϨεਪਐڠٞձ w ֤ࣄۀऀͱڞʹίʔυܾࡁʹؔ͢Δٕज़ͳ౷Ұ࢓༷ Λཱ֬͠ɺΨΠυϥΠϯΛࡦఆ w 23ίʔυͷσʔλϑΥʔϚοτ w γεςϜͷશମઃܭ

    w ηΩϡϦςΟཁ݅ͳͲ w ͻͱͭͷ23ίʔυͰෳ਺ͷܾࡁαʔϏε͕ར༻Մೳ IUUQTXXXQBZNFOUTKBQBOPSKQKQRS 23ίʔυ͸ ג σϯιʔ΢Σʔϒͷొ࿥঎ඪͰ͢
  11. ౷Ұ23ίʔυ࢓༷ w &.7࢓༷ $1. ˞ ͱڞଘՄೳͳ࢓༷ w ಛఆλάΛݟΔͱ+123ϑΥʔϚοτ͔ &.7 $1.

    ϑΥʔϚοτ͔൑ผͰ͖Δ w ւ֎ͷίʔυܾࡁࣄۀऀͷίʔυͱͷࣝผ͕Մೳ ˞&.7 $1. &.7$P -$$ ˞ ͕ࡦఆͨ͠άϩʔόϧͳ23ίʔυܾࡁ࢓༷
 ˞&.7$P-$$&.7 ˞ ࢓༷ͳͲΛࡦఆ͢Δٕज़ஂମ
 ˞&.7*$ܕΫϨδοτΧʔυͷ౷Ұن֨ IUUQTXXXFNWDPDPNFNWUFDIOPMPHJFTRSDPEFT
  12. l+12399'//////ʜz σίʔυ 5BH આ໌ ௕͞ ஋  ϖΠϝϯτϑΥʔϚοτࣝผࢠ  l+123z

     ΞϓϦέʔγϣϯςϯϓϨʔτ Մม௕ ʜ ' "%'/BNF ϒϥϯυࣝผࢠ Մม௕ lz  5SBDL *%౳ Մม௕ ܾࡁ*% 5-7 λά ௕͞ ஋ ܗࣜ +123 ϑΥʔϚοτ lࣄۀऀࣝผίʔυ ܻ z lτʔΫϯ෦ /ܻ z
 ˠ౷Ұόʔίʔυͱڞ௨
  13. 23ίʔυόʔίʔυͷදࣔ import CoreImage import Foundation let payload = “8505JPQR164XX4F08123456785712345678NNNNN." //

    QRίʔυ let filter = CIFilter(name: "CIQRCodeGenerator")! let data = string.data(using: .utf8) filter.setValue(data, forKey: "inputMessage") filter.setValue("H", forKey: "inputCorrectionLevel") let image = UIImage(ciImage: filter.outputImage!) // όʔίʔυ let filter = CIFilter(name: “CICode128BarcodeGenerator")! จࣈྻɾɾɾ
  14. lKQPSQBZNFOUTKBQBOBBBBBBBB BBBBBCCCCDDDDDDEEEEEE ʜz *% આ໌ ௕͞ ஋ lz ࢓༷WFSTJPO 

    lz lz ੩తಈతϑϥά  lz ੩త lz ܖ໿ళ৘ใ  ܖ໿ళ৘ใ lz औҾ௨՟  lz ԁ lz औҾֹۚ ೚ҙ   ʜ ʜ ʜ ʜ *% આ໌ ௕͞ ஋ lz (MPCBM6OJRVF*EFOUJpFS  lKQPSQBZNFOUTKBQBOz lz ౷Ұళฮࣝผίʔυ؅ཧϨϕϧ1  lBBBBBBBBBBBBBz lz ౷Ұళฮࣝผίʔυ؅ཧϨϕϧ2  lCCCCz lz ౷Ұళฮࣝผίʔυ؅ཧϨϕϧ3  lDDDDDDz lz ౷Ұళฮࣝผίʔυ؅ཧϨϕϧ4  lEEEEEEz ܖ໿ళ৘ใ ୺຤εςοΧʔྫ l൪ςʔϒϧz ܖ໿ళྫ z৽ڮ̍߸ళz ϒϥϯυྫ z˓˓԰z ๏ਓྫ l˓˓גࣜձࣾz σίʔυ
  15. 23ίʔυͷεΩϟϯ import AVFoundation let session = AVCaptureSession() let input =

    try! AVCaptureDeviceInput(device: videoDevice) var output = AVCaptureMetadataOutput() output.setMetadataObjectsDelegate(self, queue: …) session.addInput(input) session.addOutput(self.output) output.metadataObjectTypes = [.qr] session.startRunning() extension …: AVCaptureMetadataOutputObjectsDelegate { public func metadataOutput(.., meta: [AVMetadataObject],..) { … = meta.compactMap { in if let code = $0 as? AVMetadataMachineReadableCodeObject, code.type == .qr, let val = code.stringValue { return val
  16. QSPUPDPM233FBEFS5ZQF\
 GVODNFUBEBUB0VUQVU QBZMPBE4USJOH 
 ^ DMBTT233FBEFS233FBEFS5ZQF\
 GVODNFUBEBUB0VUQVU QBZMPBE4USJOH \
 MFUTFTTJPO"7$BQUVSF4FTTJPOʜ


    ʜ ^ 3FMFBTF#VJME DMBTT233FBEFS4UVC233FBEFS5ZQF\
 GVODNFUBEBUB0VUQVU QBZMPBE4USJOH \
 SFUVSOl%6..:@7"-6&z ^
 ^ %FCVH#VJME ྫ %*ʹΑΔΧϝϥϞδϡʔϧͷ ελϒԽ
  17. ·ͱΊ wϞόΠϧܾࡁΞϓϦͷഎܠͱߏ੒ٕज़ wΩϟογϡϨεਪਐڠٞձ $BTI*O $BTI0VU  F ,:$ w"QQMF1BZ w"QQMF1BZ࢓૊Έ

    ηΩϡϦςΟ *O"QQ1SPWJTJPOJOH wίʔυܾࡁ w+123࢓༷ $1..1.ͷ࢓༷ wطଘΞϓϦ΁ͷܾࡁػೳͷ૊ΈࠐΈ wGSBNFXPSL෼ׂͱTBOECPY %*