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

D2f212ce418f3daa29c23914c9b6892b?s=47 Kentaro Matsumae
September 07, 2019

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

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

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

D2f212ce418f3daa29c23914c9b6892b?s=128

Kentaro Matsumae

September 07, 2019
Tweet

Transcript

  1. 11.
  2. 12.

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

    ۜߦޱ࠲ৼࠐ 8BMMFU $BTI*O $BTI0VU લ෷ࣜࢧ෷͍खஈൃߦۀ ϙΠϯτ IUUQTXXXTLFTTBJKQJOGPMBXIUNM
  3. 13.

    "QQMF1BZ ίʔυܾࡁ ωοτܾࡁ ݸਓؒૹۚ ۜߦޱ࠲ৼࠐ 8BMMFU $BTI*O $BTI0VU ۜߦޱ࠲νϟʔδ ίϯϏχ"5.

    νϟʔδ ΫϨδοτΧʔυ ݸਓؒૹۚ ϑϦϚΞϓϦച্ۚ ऩೲ୅ߦۀ ˞ٞ࿦͋Γ ˞஫ IUUQTTUPSJBMBXKQCMPH
  4. 14.

    "QQMF1BZ ίʔυܾࡁ ωοτܾࡁ ݸਓؒૹۚ ۜߦޱ࠲ৼࠐ 8BMMFU $BTI*O $BTI0VU ۜߦޱ࠲νϟʔδ ίϯϏχ"5.

    νϟʔδ ΫϨδοτΧʔυ ݸਓؒૹۚ ϑϦϚΞϓϦച্ۚ ࢿۚҠಈۀ IUUQTXXXTLFTTBJKQJOGPMBXIUNM
  5. 15.

    ࢿۚҠಈۀ d w ۜߦ౳Ҏ֎ͷऀ͕ҝସऔҾΛۀͱͯ͠ӦΉ΋ͷ w ಺ֳ૯ཧେਉͷొ࿥͕ඞཁ w ̍ճ͋ͨΓͷૹֹۚສԁҎԼ w ߴ౓ͳ૊৫੔උ

    w ࡒ੓ج൫੔උ w ൜ࡑऩӹҠస๷ࢭ๏ͷن੍Λड͚Δ ࢿܾۚࡁ๏ୈࡾेࣣ৚ IUUQTFMBXTFHPWHPKQTFBSDIFMBXT4FBSDIFMBXT@TFBSDIMTHEFUBJM MBX*E"$
  6. 16.

    ൜ࡑऩӹҠస๷ࢭ๏ w ൜ࡑऩӹͷҠసʢʹϚωʔϩϯμϦϯάʣͳ ͲΛ๷ࢭ͢ΔͨΊͷ๏཯ w औҾ࣌֬ೝٛ຿ w औҾ࣌ʹຊਓ֬ೝ ,:$ ͕ඞཁ

    w Ͳ͏΍ͬͯʁ ൜ࡑʹΑΔऩӹͷҠస๷ࢭʹؔ͢Δ๏཯ୈ࢛৚ IUUQTFMBXTFHPWHPKQTFBSDIFMBXT4FBSDIFMBXT@TFBSDIMTHEFUBJM MBX*E"$ ,:$,OPX:PVS$VTUPNFS
  7. 20.

    "QQMF1BZ ίʔυܾࡁ ωοτܾࡁ ݸਓؒૹۚ ۜߦޱ࠲ৼࠐ 8BMMFU $BTI*O $BTI0VU ۜߦޱ࠲νϟʔδ ίϯϏχ"5.νϟʔδ

    ΫϨδοτΧʔυ ݸਓؒૹۚ ϑϦϚΞϓϦച্ۚ ຊਓ֬ೝ ,:$ ϞόΠϧܾࡁΞϓϦͷߏ੒ཁૉ
  8. 21.
  9. 23.

    J04 %FWJDF "QQMF τʔΫϯ ϓϩόΠμʔ wΧʔυ໊ٛ wΧʔυ൪߸ '1"/  wηΩϡϦςΟίʔυ

    %1"/ 4FDVSF &MFNFOU IUUQTTVQQPSUBQQMFDPNKBKQ)5 "QQMF1BZͷΧʔυొ࿥ϑϩʔ '1"/ˠ%1"/ ੜͷΧʔυ൪߸ͱ͸ผͷΧʔυ ൪߸ʢ%1"/τʔΫϯʣʹม׵
  10. 24.

    J04 %FWJDF ͓ళ τʔΫϯ ϓϩόΠμʔ "VUI ✅ %1"/ 4FDVSF &MFNFOU

    Χʔυ ձࣾ "QQMF1BZͷܾࡁϑϩʔ %1"/ˠ'1"/ '1"/ J04σόΠεʙτʔΫϯϓϩόΠμʔؒͰ ੜͷΧʔυ൪߸ '1"/ Λྲྀͣ͞ʹܾࡁՄೳ
  11. 28.

    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
  12. 34.

    +123 w ΩϟογϡϨεਪਐڠٞձ w ֤ࣄۀऀͱڞʹίʔυܾࡁʹؔ͢Δٕज़ͳ౷Ұ࢓༷ Λཱ֬͠ɺΨΠυϥΠϯΛࡦఆ w 23ίʔυͷσʔλϑΥʔϚοτ w γεςϜͷશମઃܭ

    w ηΩϡϦςΟཁ݅ͳͲ w ͻͱͭͷ23ίʔυͰෳ਺ͷܾࡁαʔϏε͕ར༻Մೳ IUUQTXXXQBZNFOUTKBQBOPSKQKQRS 23ίʔυ͸ ג σϯιʔ΢Σʔϒͷొ࿥঎ඪͰ͢
  13. 39.

    ౷Ұ23ίʔυ࢓༷ w &.7࢓༷ $1. ˞ ͱڞଘՄೳͳ࢓༷ w ಛఆλάΛݟΔͱ+123ϑΥʔϚοτ͔ &.7 $1.

    ϑΥʔϚοτ͔൑ผͰ͖Δ w ւ֎ͷίʔυܾࡁࣄۀऀͷίʔυͱͷࣝผ͕Մೳ ˞&.7 $1. &.7$P -$$ ˞ ͕ࡦఆͨ͠άϩʔόϧͳ23ίʔυܾࡁ࢓༷
 ˞&.7$P-$$&.7 ˞ ࢓༷ͳͲΛࡦఆ͢Δٕज़ஂମ
 ˞&.7*$ܕΫϨδοτΧʔυͷ౷Ұن֨ IUUQTXXXFNWDPDPNFNWUFDIOPMPHJFTRSDPEFT
  14. 40.

    l+12399'//////ʜz σίʔυ 5BH આ໌ ௕͞ ஋  ϖΠϝϯτϑΥʔϚοτࣝผࢠ  l+123z

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

    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")! จࣈྻɾɾɾ
  16. 48.

    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 σίʔυ
  17. 49.

    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
  18. 60.

    QSPUPDPM233FBEFS5ZQF\
 GVODNFUBEBUB0VUQVU QBZMPBE4USJOH 
 ^ DMBTT233FBEFS233FBEFS5ZQF\
 GVODNFUBEBUB0VUQVU QBZMPBE4USJOH \
 MFUTFTTJPO"7$BQUVSF4FTTJPOʜ


    ʜ ^ 3FMFBTF#VJME DMBTT233FBEFS4UVC233FBEFS5ZQF\
 GVODNFUBEBUB0VUQVU QBZMPBE4USJOH \
 SFUVSOl%6..:@7"-6&z ^
 ^ %FCVH#VJME ྫ %*ʹΑΔΧϝϥϞδϡʔϧͷ ελϒԽ
  19. 61.

    ·ͱΊ wϞόΠϧܾࡁΞϓϦͷഎܠͱߏ੒ٕज़ wΩϟογϡϨεਪਐڠٞձ $BTI*O $BTI0VU  F ,:$ w"QQMF1BZ w"QQMF1BZ࢓૊Έ

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