มาทำ In-App Purchases ใน iOS กันเถอะ :D

Taratorn D.
Krungsri Consumer-Innovation
4 min readApr 26, 2021
Photo by Marvin Meyer on Unsplash

บทความนี้เกิดจากการที่ผมได้มีโอกาสได้ทำโปรเจ็คที่มีการซื้อสินค้าหรือเนื้อหาออนไลน์ เลยมานั่งค้นคว้าดูว่าการทำ In-App Purchase มันทำยังไงบ้างนะ เลยได้มีโอกาสได้เอามาแชร์กันครับ

ก่อนอื่นเลยถ้าจะทำ In-App Purchase เราต้องรู้ก่อนว่าทาง Apple เค้ามีสินค้าประเภทอะไรบ้างที่ให้เราใช้ได้บ้าง

ประเภทของสินค้า

ทาง Apple จะมีประเภทสินค้าด้วยกัน 4 แบบคือ

  1. Consumables คือ สินค้าประเภทสิ้นเปลือง โดยผู้ใช้สามารถซื้อซ้ำได้ เช่น เหรียญในเกมส์ เป็นต้น
  2. Non-Consumables คือ สินค้าที่ไม่ใช่ประเภทสิ้นเปลือง โดยผู้ใช้สามารถซื้อได้ครั้งเดียวและไม่มีวันหมดอายุ เช่น หนังสือ รูปภาพ เป็นต้น
  3. Auto-Renewable Subscriptions คือ บริการ หรือ เนื้อหา ที่ผู้ใช้สามารถซื้อครั้งเดียวและต่ออายุอัตโนมัติจนกว่าผู้ใช้จะตัดสินใจยกเลิก
  4. Non-renewing subscription คือ บริการ หรือ เนื้อหาที่ให้ผู้ใช้เข้าถึงในช่วงเวลาที่จำกัด และไม่ต่ออายุอัตโนมัติ ผู้ใช้สามารถซื้อซ้ำได้

การจัดการสินค้า

เราสามารถเพิ่ม ลบ แก้ไข ข้อมูลสินค้าได้ที่ https://appstoreconnect.apple.com/ โดยเข้าไปที่เมนู Manage ใน In-App Purchases โดยสามารถกดเครื่องหมาย “+” เพื่อเพิ่มสินค้า

หน้าจัดการสินค้า

ตั้งค่าโปรเจ็คเบื้องต้น

เริ่มแรกให้สร้างตัวโปรเจ็คขึ้นมาก่อน ในเดโมตัวนี้ผมใช้เป็น ภาษา Swift ส่วน Interface เป็น Storyboard ครับ

สร้างโปรเจ็ค

หลังจากนั้นให้เราทำการเพิ่ม In-App Purchase ใน Capability

เพิ่ม In-App Purchase ใน Capability

ในตัวอย่างนี้ผมจะใช้ตัวไฟล์ StoreKit Configuration ในการเพิ่ม Product โดยให้ทำการ New File -> เลือก StoreKit Configuration File

สร้าง StoreKit config file

เสร็จแล้วเราต้องตั้งค่าให้ Scheme ที่เราต้องการรันนั้นเรียกใช้ไฟล์ StoreKit Configuration ตัวนี้โดยเข้าไปที่ Edit Scheme เลือกเมนู Options -> StoreKit Configuration

ตั้งค่าการเรียกไฟล์ StoreKit Config

ถ้าต้องการใช้กับสินค้าที่อยู่บน AppStoreConnect อย่าลืมเอาตัวนี้ออกนะ เคยลืมเอาออกแล้ว Fetch Product ไม่ตรงหาเกือบครึ่งวันแหนะ -_-”

การ Fetch Product

ในการดึงข้อมูล Product สิ่งแรกที่เราต้องรู้คือ Product IDs เพราะเป็นสิ่งที่เราจะใช้อ้างอิงในการ Fetch ข้อมูล ทีนี้เราจะทำการสร้าง Function สำหรับการดึงข้อมูล Product ดังนี้

  1. เราจะต้องสร้าง Request ผ่าน SKProductsRequest โดยค่าเป็น Set<String> ซึ่งเราสามารถ Fetch Product ได้มากว่า 1 Id
  2. ให้เพิ่ม Protocol ที่ชื่อ SKProductsRequestDelegate เพื่อรอรับ Callback ตัว Product เวลา fetch สำเร็จ
  3. หลังจากเพิ่ม SKProductsRequestDelegate แล้วจะถูก Require function ที่ชื่อ productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) ให้เพิ่มเข้าไปเพราะเมื่อ Fetch Product เสร็จจะมาเข้า Callback ที่ function ตัวนี้โดยเราสามารถเอาค่า Product จาก response.products มาใช้ต่อได้ โดย Object ของ Product จะชื่อว่า SKProduct
  4. หลังจากนั้น start request โลด โดยใช้คำสั่ง start()
func fetchProduct(productIds: Set<String>) {   let request = SKProductsRequest(productIdentifiers: productIds)   request.delegate = self   request.start()}func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {   print(response.products)}

การทำ Purchase

หลังจากที่เราได้ SKProduct มาแล้วทีนี้เราก็จะมาทำ Purchase โดย step จะมีดังนี้

  1. ทำการเช็คว่า Device เครื่องนี้สามารถทำ Payment ได้หรือไม่ โดยการเรียก SKPaymentQueue.canMakePayments() ค่า return ที่ได้จะเป็น Boolean ถ้าเป็น true สามารถทำ Payment ได้
  2. สร้าง Object ที่ชื่อ SKPayment โดยนำ Parameter ของ SKProduct ที่เรา Fetch ได้มาใส่
  3. ทำการ Add transaction observer ผ่าน SKPaymentQueue.default().add(self) โดย function นี้จะรับ Delegate Callback เมื่อมี Process Transaction เกิดขึ้น หรือ มีการ Update Transaction
  4. เพิ่ม SKPaymentTransactionObserver และ Implement function ที่ชื่อ paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) โดยเมื่อมี Transaction เกิดขึ้นจะถูก Callback มาที่ function นี้
  5. ทำการ add SKPayment เข้าไปในคิวด้วยคำสั่ง SKPaymentQueue.default().add(payment)
  6. ให้เราทำการดัก State ของ Transaction โดย state จะมีด้วยกัน 5 แบบคือ purchasing, purchased, failed, restored, deferred
  7. เมื่อเราทำ Process ต่างๆ เสร็จแล้วให้ใช้คำสั่ง SKPaymentQueue.default().finishTransaction(transaction) เพื่อเสร็จสิ้นการทำ Transaction นี้
func makePayment(product: SKProduct) {   guard SKPaymentQueue.canMakePayments() else { return }   let payment = SKPayment(product: product)   SKPaymentQueue.default().add(self)   SKPaymentQueue.default().add(payment)}func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {   transactions.forEach { transaction in      switch transaction.transactionState {         case .purchasing:            print("transaction is on process purchasing")         case .purchased:            /// Update to server            SKPaymentQueue.default().finishTransaction(transaction)         case .failed:            /// Update to server            SKPaymentQueue.default().finishTransaction(transaction)         case .restored:            break         case .deferred:            break         @unknown default:            break       }    }}

พอเสร็จแล้วก็ลองรันดูกันเลย

สร้าง User Sandbox

เราสามารถสร้าง Sandbox user เพื่อเอามาทดสอบ IAP ที่เราสร้างไว้ โดยเข้าไปที่ https://appstoreconnect.apple.com/ เมนู Users and Access จากนั้นมองหาหัวข้อ Sandbox บนแถบเมนูด้านซ้ายมือ จากนั้นเลือก Testers

ถ้าต้องการเพิ่ม User sandbox ให้กดที่เครื่องหมาย “+” จากนั้นจะมีฟอร์มให้กรอก ชื่อ นามสกุล อีเมลล์ พาสเวิร์ด ต่างๆ

สร้าง User Sandbox

หมายเหตุ: อีเมลล์ที่ใช้จะต้องไม่ใช่ Apple Id ที่มีอยู่

เพียงเท่านี้เราก็สามารถสร้าง app ที่ทำ In-App Purchase ได้ง่าย ๆ ครับ นี่เป็นบทความแรกของผม หากผิดพลาดประการใดสามารถ Comment ชี้แจงให้แก้ไขได้นะครับ 🙂

ยังมีเนื้อหาอื่นๆ ที่ผมอาจจะตกหล่นไปบ้างสามารถ หาอ่านเพิ่มเติมได้ที่นี่ครับ

SourceCode

https://github.com/x3T4R4T0RN/iap-demo

--

--