ลองเล่น LINE PAY API ผ่านระบบสั่งอาหารออนไลน์

Sitthi Thiammekha
LINE Developers Thailand
5 min readSep 15, 2018

วันนี้ผมได้มีโอกาสไปเป็น Mentor ในงาน LINE HACK 2018 ที่จัดขึ้นที่ออฟฟิต LINE Thailand ก็มีคนมาถามเกี่ยวกับ LINE PAY API พอสมควร ก็เลยต้องถือโอกาสปล่อยบทความที่ดองมานานอันนี้ซักที

ผมเคยทำระบบสั่งอาหารออนไลน์ไว้นานแล้ว เป็นแบบที่ลูกค้าสามารถเปิดดูเมนูและสั่งอาหารได้เลย ในหน้าจอ LIFF ที่ดึงเอาเวบ React มาแสดงอีกที จากนั้นก็ทำการรับชำระเงินจาก LINE PAY ได้เลย

ในบทความนี้ ก็ยกเอาส่วนที่เกี่ยวกับ LINE PAY API มาให้ดูกันครับ
โดยแบ่งเป็น 3 ส่วนคือ

  • การสร้างบัญชี Sandbox เพื่อทดสอบ
  • ทำความรู้จัก LINE PAY API
  • การเชื่อมต่อ LINE PAY API

1. การสร้างบัญชี Sandbox เพื่อทดสอบ

ในเวบ developer ของ pay.line.me ได้ระบุ ขั้นตอนการทดสอบ ไว้เป็นลำดับดังนี้

เราจะเริ่มจากการสร้างบัญชี Sandbox ก่อนครับ

เข้าไปที่ https://pay.line.me/jp/developers/techsupport/sandbox/creation?locale=th_TH จะเจอหน้าจอแบบนี้

กรอกรายละเอียดให้ครบ แล้ว Submit เลยครับ จะเห็นหน้าจอแบบข้างล่างนี้

ใครอยากอ่าน document ประกอบ ก็ลองกดอ่านดูด้วยก็ได้ครับ

ตอนนี้คุณจะได้รับอีเมล์ หน้าตาแบบนี้

ให้ใช้ ID และ PW ที่ได้มา ไป Login เข้าที่เวบตาม Link ในอีเมล์เลยครับ

ย้ำ!! ให้ใช้ ID และ PW ที่ได้จากในเมล์นะครับ ไม่ใช่เข้าด้วย LINE ของตัวเอง

เข้ามาจะเข้าหน้าจอแบบนี้ครับ

ให้เข้าไปที่เมนู การจัดการการเชื่อมต่อระบบชำระเงิน > จัดการ Link Key
ระบบจะให้เราใส่รหัสผ่านอีกครั้ง

จะเจอหน้าจอ จัดการ Link Key ให้ copy Channel ID กับ Channel Secret Key เอาไว้นะครับ เดี๋ยวเราจะต้องใช้สองค่านี้

*** Channel ID กับ Channel Secret Key นี้ เป็นคนละชุดกับเวลาสร้าง Bot Channel จาก Developers Console นะครับ ใช้แยกกัน ***

เสร็จละครับ การสร้างบัญชี Sandbox เดี๋ยวขั้นตอนต่อไป เราจะไปทำความรู้จักกับ LINE PAY API กัน

Ref:

2. ทำความรู้จัก LINE PAY API

จากเอกสารแนะนำการเชื่อมต่อ จะเห็นแผนภาพการทำงานของ LINE PAY API ดังนี้

ด้านซ้ายคือการเรียกใช้งาน API ส่วนด้านขวาคือสถานะของการชำระเงินที่เกิดขึ้นจากการเรียก API

ขออธิบายคร่าวๆ ดังนี้ครับ

  • Reserve API หรือ การจองชำระเงิน
    ทุกครั้งที่ต้องการเริ่ม transaction การจ่ายเงิน จะต้องเรียก API ตัวนี้
    สิ่งที่เราจะได้รับกลับมาคือ paymentUrl สำหรับให้ลูกค้าไปชำระเงิน
  • Confirm API หรือ การยืนยันการชำระเงิน
    เป็นการยืนยันรายการจากฝั่งร้านค้าว่ารายการสำเร็จแล้ว
    เมื่อเรียก API นี้ สามารถกำหนดให้ เรียกจัดเก็บเงินจากระบบโดยอัตโนมัติ หรือจะเรียกจัดเก็บเงินเองภายหลังก็ได้ (กรณีหลัง มักใช้กรณีที่ต้องการ settle รายการตอนสิ้นวัน เผื่อกรณีลูกค้ามา void ได้)
  • Capture API หรือ การจัดเก็บเงิน
    เป็นการเรียก settle รายการ และจัดเก็บเงิน หลังจากจัดเก็บเงินแล้ว จะไม่สามารถ Void รายการได้ ต้องไปใช้การ Refund แทน
  • Void API หรือ การยกเลิกการชำระเงิน
    เป็นการยกเลิกรายการชำระเงินที่ยังไม่ได้จัดเก็บ
  • Refund API หรือ การคืนเงิน
    เป็นการคืนเงินจากรายการที่มีการจัดเก็บเงินไปแล้ว

นอกจากนี้ ยังรองรับการชำระเงินแบบล่วงหน้าได้ด้วย (Preapprove Payment / Recurring Payment)

โดยวันนี้ผมจะพาทำในส่วนของ Reserve API และ Confirm API แบบให้จัดเก็บอัตโนมัติ นะครับ ไปเริ่มกันเลย

3. การเชื่อมต่อ LINE PAY API

การเชื่อมต่อ LINE PAY API ต้องกำหนด Header ของ POST Request ดังนี้

โดย X-LINE-ChannelId และ X-LINE-ChannelSecret ได้มาจากหน้าจัดการ Link Key ก่อนหน้านี้

ใน code ก็จะหน้าตา ประมาณนี้ครับ

ก่อนจะไปเริ่มเชื่อมต่อ ผมจะให้ดูหน้าจอประกอบไปด้วย จะได้เข้าใจว่า เราต้องเชื่อมต่อกับ LINE PAY ในขั้นตอนไหนบ้าง

ผมได้ทำบอทง่ายๆไว้ตัวหนึ่ง สำหรับกดสั่งอาหาร หน้าตาก็ประมาณนี้

พอกดที่เมนู สั่งอาหาร จะเปิด LIFF ขึ้นมา เป็นหน้าเวบให้เรากดสั่งอาหารจากเมนู
เมื่อสั่งอาหารจนเป็นที่พอใจแล้ว ก็จะสรุปรายการด้านล่าง พร้อมปุ่ม LINE PAY ขึ้นมา

เมื่อผู้ใช้กดชำระเงินด้วย LINE PAY ผมจะส่งรายการอาหารไปจัดเก็บไว้ที่ server ก่อน จากนั้นจึงเริ่มทำการเรียก Reserve API เพื่อจองการชำระเงิน

โดยผมทำเป็น Firebase Cloud Function ไว้หน้าตาแบบนี้

ผมส่ง productName, amount, orderId มาจาก client

ส่วน payload คือข้อมูลที่ผมจะ POST ไปที่ LINE PAY API มีรายละเอียดดังนี้

productName * — เป็นชื่อรายการที่จะแสดงในหน้าชำระเงิน
amount * — จำนวนเงิน
orderId * — เลขคำสั่งซื้อ ใช้ในการอ้างอิงรายการ
currency * — สกุลเงิน
confirmUrl * — เป็น url สำหรับให้ LINE PAY ส่งข้อมูลกลับมา เมื่อชำระเงินสำเร็จ
confirmUrlType — เป็นประเภทของ confirm url มี 2 ประเภทคือ
* CLIENT : หมายถึงให้ redirect browser ไปยัง url ที่กำหนด (Default)
* SERVER : หมายถึงให้แสดงข้อความว่าชำระเงินสำเร็จ แล้วยิง request ไปยัง url ที่กำหนด

ส่วนที่เป็นตัวหนา * คือ parameter ที่ required นอกจากนี้ยังสามารถกำหนด optional parameter ได้อีกหลายตัว มีตัวที่น่าสนใจ เช่น

productImageUrl — รูปสินค้า
payType — ประเภทการชำระเงิน
* NORMAL:การชำระเงินแบบปกติ (Default)
* PREAPPROVED: การชำระเงินที่อนุมัติไว้ล่วงหน้า
langCd — ภาษาในหน้าจอชำระเงิน
capture — ระบุให้จัดเก็บเงินทันที (true-Default) / จัดเก็บเงินเองภายหลัง (false)
extras.addFriends — ระบุให้เพิ่มเพื่อนกับ LINEID ที่ระบุ

ลองศึกษาจากใน document เพิ่มเติมได้นะครับ ในบทความนี้ ผมจะใส่เฉพาะที่จำเป็นก่อน

เมื่อยิง Request นี้ไป จะได้ Response หน้าตาประมาณนี้ครับ

{
"returnCode": "0000",
"returnMessage": "Success.",
"info": {
"paymentUrl": {
"web": "https://sandbox-web-pay.line.me/web/payment/wait?transactionReserveId=ZU5XcGYxxxxx&locale=th_LP",
"app": "line://pay/payment/ZU5XcGY4Q3JUdjxxxxx"
},
"transactionId": 201809150003xxxxx,
"paymentAccessToken": "0426204xxxxx"
}
}

ส่วนที่จะนำไปใช้ต่อก็คือ paymentUrl กับ transactionId ที่ได้มา
โดย paymentUrl จะมี 2 แบบคือ web และ app

  • web จะพาผู้ใช้ไปหน้าจอชำระเงินบน browser
  • app จะเปิดหน้า LINE PAY บนแอพขึ้นมา

ใน Sandbox เราจะใช้ได้แค่แบบ web นะครับ
เมื่อเราได้ paymentUrl มาแล้ว ผมก็ให้ client เปิดไปที่ paymentUrl.web เพื่อพาผู้ใช้ไปหน้าชำระเงิน ดังรูป

ถ้าเป็นการเชื่อมต่อกับ API จริง จะแสดงหน้าจอให้ลูกค้าเลือกวิธีการชำระเงิน เช่น ให้ตัดจาก wallet หรือ ตัดเงินจากบัตรเครดิต ตรงนี้มีข้อควรระวังนิดนึงคือ

ถ้าต้องการทดสอบบน API จริง แนะนำให้ใช้เงินใน Wallet เพื่อที่จะได้คืนเงินภายในสิ้นวันได้ ถ้าทดลองจ่ายเงินโดยการใช้บัตร Credit Card กว่าจะได้เงินคืนอาจจะต้องรอถึง 90 วัน

ส่วนบทความนี้เป็น Sandbox ก็จะลัดขั้นตอนการเลือกวิธีการชำระเงินไปเลย พอกด PAY NOW ก็ได้เป็นหน้าตาแบบนี้

ในตอนนี้ LINE จะทำการส่ง GET request ไปที่ confirmUrl ที่เรากำหนดไว้ตอนเรียก Reserve API พร้อมกับ query string 2 ตัวคือ transactionId และ orderId เพื่อใช้ในการอ้างอิงกับระบบของเรา เท่าที่ผมทดสอบ transactionId นี้ จะไม่ตรงกับ transactionId ที่ได้มาตอนเราเรียก reserve API แต่ orderId จะเป็นเลขเดียวกัน

เราต้องทำการสร้าง function รับ request นี้ เพื่อทำการเรียก confirm API กลับไปที่ LINE อีกครั้ง ประมาณนี้

สิ่งที่เราส่งไปใน confirm API ก็มีเพียงแค่ amount และ currency เท่านั้น เมื่อเราเรียก confirm API ก็จะได้ response กลับมา ประมาณนี้ครับ

{
"returnCode": "0000",
"returnMessage": "Success.",
"info": {
"transactionId": 2018091600034225200,
"orderId": "1537036445842",
"payInfo": [
{
"method": "CREDIT_CARD",
"amount": 240
}
]
}
}

ถึงตอนนี้ เท่ากับว่า เราทำการจัดเก็บเงินเรียบร้อยแล้ว ก็ทำการบันทึกสถานะคำสั่งซื้อ และแจ้งให้ผู้ใช้ทราบ

ผู้ใช้ก็จะได้รับข้อความแบบนี้

เราสามารถตรวจสอบสถานะการชำระเงินได้อีกทางหนึ่งจาก Merchant Center

ลองดูที่เมนู ประวัติธุรกรรม จะไม่พบรายการธุรกรรมใดใด ไม่ต้องตกใจครับ เพราะเรากำลังอยู่ใน Sandbox ให้เข้าไปที่เมนู Sandbox ตรงที่วงไว้ครับ ถ้าใครเจอภาษาญี่ปุ่นก็ไปเปลี่ยนเป็นภาษาไทยตรงมุมบนขวาสุดครับ

จะเจอหน้าตาแบบนี้ พอกดค้นหาก็จะเจอรายการที่ทำไปทั้งหมดครับ

เป็นอันว่า เราเชื่อมต่อกับ LINE PAY API เรียบร้อยละครับ

ใครสนใจศึกษา code ผมแชร์ไว้แล้วที่ github

จบปิ๊ง

ขอให้สนุกกับ LINE PAY API ครับ

--

--