Android SDK
Omise Android SDK ให้บริการโซลูชันที่ครอบคลุมสำหรับการผสานรวมการประมวลผลการชำระเงินเข้ากับแอปพลิเคชัน Android ของคุณ สร้างขึ้นด้วย Kotlin และเข้ากันได้อย่างสมบูรณ์กับ Java โดยให้บริการการสร้าง token ที่ปลอดภัย คอมโพเนนต์ Material Design แบบ native และรองรับวิธีการชำระเงินหลักทั้งหมดในเอเชียตะวันออกเฉียงใต้
ภาพรวม
Android SDK ช่วยให้คุณสามารถ:
- สร้าง token บัตรเครดิต อย่างปลอดภัยโดยไม่ให้ข้อมูลที่ละเอียดอ่อนเข้าถึงเซิร์ฟเวอร์ของคุณ
- สร้าง payment source สำหรับวิธีการชำระเงินทางเลือก
- ใช้งาน 3D Secure authentication ด้วย Chrome Custom Tabs
- สร้างฟอร์มการชำระเงินที่กำหนดเอง ด้วยคอมโพเนนต์ Material Design
- รองรับการยืนยันตัวตนแบบไบโอเมตริกซ์ ด้วยลายนิ้วมือและการปลดล็อกใบหน้า
- จัดการข้อผิดพลาดอย่างเหมาะสม ด้วยการจัดการข้อยกเว้นที่ครอบคลุม
คุณสม บัติหลัก
- Native Kotlin API พร้อมรองรับ coroutines
- ความเข้ากันได้กับ Java อย่างสมบูรณ์สำหรับโปรเจกต์เก่า
- คอมโพเนนต์ UI Material Design ที่สร้างไว้ล่วงหน้า
- รองรับ Jetpack Compose
- การตรวจสอบความถูกต้องของข้อมูลนำเข้าที่ครอบคลุม
- ความยืดหยุ่นของเครือข่ายด้วยการลองใหม่อัตโนมัติ
- ตัวสร้างคำขอที่ปลอดภัยต่อประเภท
- รองรับ AndroidX และ Material Components
ข้อกำหนด
- Android API Level 21 (Android 5.0) หรือสูงกว่า
- Android Studio Arctic Fox หรือใหม่กว่า
- Kotlin 1.5+ หรือ Java 8+
- Gradle 7.0+
- ไลบรารี AndroidX
การติดตั้ง
Gradle (แนะนำ)
เพิ่ม SDK เข้าไปใน build.gradle ของแอปคุณ:
dependencies {
implementation 'co.omise:omise-android:4.0.0'
}
สำหรับ Kotlin DSL (build.gradle.kts):
dependencies {
implementation("co.omise:omise-android:4.0.0")
}
Maven
<dependency>
<groupId>co.omise</groupId>
<artifactId>omise-android</artifactId>
<version>4.0.0</version>
</dependency>
สิทธิ์
เพิ่มเข้าไปใน AndroidManifest.xml ของคุณ:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
เริ่มต้นอย่างรวดเร็ว
1. Import SDK
// Kotlin
import co.omise.android.Client
import co.omise.android.models.Token
import co.omise.android.models.Source
// Java
import co.omise.android.Client;
import co.omise.android.models.Token;
import co.omise.android.models.Source;
2. เริ่มต้น Client
// Kotlin
class PaymentManager(context: Context) {
private val client = Client("pkey_test_5xyzyx5xyzyx5xyzyx5")
}
// Java
public class PaymentManager {
private final Client client;
public PaymentManager(Context context) {
client = new Client("pkey_test_5xyzyx5xyzyx5xyzyx5");
}
}
3. สร้าง Token
ใช้ Kotlin Coroutines
import kotlinx.coroutines.*
import co.omise.android.api.RequestListener
class PaymentViewModel : ViewModel() {
fun createToken(
name: String,
number: String,
expirationMonth: Int,
expirationYear: Int,
securityCode: String
) {
viewModelScope.launch {
try {
val token = suspendCancellableCoroutine<Token> { continuation ->
val request = Token.CreateTokenRequest(
name = name,
number = number,
expirationMonth = expirationMonth,
expirationYear = expirationYear,
securityCode = securityCode
)
client.send(request, object : RequestListener<Token> {
override fun onRequestSucceed(model: Token) {
continuation.resume(model)
}
override fun onRequestFailed(throwable: Throwable) {
continuation.resumeWithException(throwable)
}
})
}
Log.d("Payment", "Token created: ${token.id}")
sendTokenToServer(token.id)
} catch (e: Exception) {
Log.e("Payment", "Error creating token", e)
handleError(e)
}
}
}
}
ใช้ Callbacks
// Kotlin
fun createToken(
name: String,
number: String,
expirationMonth: Int,
expirationYear: Int,
securityCode: String
) {
val request = Token.CreateTokenRequest(
name = name,
number = number,
expirationMonth = expirationMonth,
expirationYear = expirationYear,
securityCode = securityCode
)
client.send(request, object : RequestListener<Token> {
override fun onRequestSucceed(model: Token) {
Log.d("Payment", "Token created: ${model.id}")
sendTokenToServer(model.id)
}
override fun onRequestFailed(throwable: Throwable) {
Log.e("Payment", "Error creating token", throwable)
handleError(throwable)
}
})
}
Java
// Java
public void createToken(
String name,
String number,
int expirationMonth,
int expirationYear,
String securityCode
) {
Token.CreateTokenRequest request = new Token.CreateTokenRequest(
name,
number,
expirationMonth,
expirationYear,
securityCode
);
client.send(request, new RequestListener<Token>() {
@Override
public void onRequestSucceed(Token token) {
Log.d("Payment", "Token created: " + token.getId());
sendTokenToServer(token.getId());
}
@Override
public void onRequestFailed(Throwable throwable) {
Log.e("Payment", "Error creating token", throwable);
handleError(throwable);
}
});
}
การกำหนดค่า
การกำหนดค่า Client
// การกำหนดค่าพื้นฐาน
val client = Client("pkey_test_5xyzyx5xyzyx5xyzyx5")
// การกำหนดค่าขั้นสูง
val config = Client.Config(
publicKey = "pkey_test_5xyzyx5xyzyx5xyzyx5",
apiVersion = "2019-05-29",
timeout = 60000L, // milliseconds
enableDebug = BuildConfig.DEBUG
)
val client = Client(config)
การกำหนดค่าเครือข่าย
import okhttp3.OkHttpClient
import java.util.concurrent.TimeUnit
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build()
val client = Client(
publicKey = "pkey_test_5xyzyx5xyzyx5xyzyx5",
httpClient = okHttpClient
)
การสร้าง Token
การสร้าง Token บัตรพื้นฐาน
fun tokenizeCard(
name: String,
number: String,
expirationMonth: Int,
expirationYear: Int,
securityCode: String,
callback: (Result<Token>) -> Unit
) {
val request = Token.CreateTokenRequest(
name = name,
number = number,
expirationMonth = expirationMonth,
expirationYear = expirationYear,
securityCode = securityCode
)
client.send(request, object : RequestListener<Token> {
override fun onRequestSucceed(model: Token) {
callback(Result.success(model))
}
override fun onRequestFailed(throwable: Throwable) {
callback(Result.failure(throwable))
}
})
}
พร้อมที่อยู่สำหรับการเรียกเก็บเงิน
fun tokenizeCardWithAddress() {
val address = Token.Address(
street1 = "123 Wireless Road",
street2 = "Lumpini",
city = "Pathum Wan",
state = "Bangkok",
postalCode = "10330",
country = "TH"
)
val request = Token.CreateTokenRequest(
name = "John Doe",
number = "4242424242424242",
expirationMonth = 12,
expirationYear = 2025,
securityCode = "123",
billingAddress = address
)
client.send(request, tokenCallback)
}
การตรวจสอบก่อนสร้าง Token
import co.omise.android.util.CardValidator
fun validateAndTokenize(
number: String,
expirationMonth: Int,
expirationYear: Int,
securityCode: String
): Result<Unit> {
// ตรวจสอบหมายเลขบัตร
if (!CardValidator.isValidCardNumber(number)) {
return Result.failure(ValidationException("หมายเลขบัตรไม่ถูกต้อง"))
}
// ตรวจสอบวันหมดอายุ
if (!CardValidator.isValidExpiry(expirationMonth, expirationYear)) {
return Result.failure(ValidationException("วันหมดอายุไม่ถูกต้อง"))
}
// ตรวจ สอบ CVV
val brand = CardValidator.getCardBrand(number)
if (!CardValidator.isValidCVV(securityCode, brand)) {
return Result.failure(ValidationException("รหัสความปลอดภัยไม่ถูกต้อง"))
}
// ดำเนินการสร้าง token
createToken(number, expirationMonth, expirationYear, securityCode)
return Result.success(Unit)
}
class ValidationException(message: String) : Exception(message)
การสร้าง Payment Source
ธนาคารอินเทอร์เน็ต
fun createInternetBankingSource(
amount: Long,
bank: InternetBanking
) {
val request = Source.CreateSourceRequest(
amount = amount,
currency = "thb",
type = SourceType.InternetBanking(bank)
)
client.send(request, object : RequestListener<Source> {
override fun onRequestSucceed(model: Source) {
// นำผู้ใช้ไปยังหน้ายืนยันการชำระเงิน
model.authorizeUri?.let { uri ->
openAuthorizeUrl(uri)
}
}
override fun onRequestFailed(throwable: Throwable) {
handleError(throwable)
}
})
}
// การใช้งาน
createInternetBankingSource(
amount = 100000L, // 1,000.00 THB
bank = InternetBanking.BAY
)
Mobile Banking
fun createMobileBankingSource(
amount: Long,
bank: MobileBanking
) {
val request = Source.CreateSourceRequest(
amount = amount,
currency = "thb",
type = SourceType.MobileBanking(bank)
)
client.send(request, sourceCallback)
}
// การใช้งาน
createMobileBankingSource(
amount = 50000L, // 500.00 THB
bank = MobileBanking.SCB
)
PromptPay
fun createPromptPaySource(amount: Long) {
val request = Source.CreateSourceRequest(
amount = amount,
currency = "thb",
type = SourceType.PromptPay
)
client.send(request, object : RequestListener<Source> {
override fun onRequestSucceed(model: Source) {
// แสดง QR code ให้กับผู้ใช้
model.scanQRCodeUrl?.let { url ->
displayQRCode(url)
}
}
override fun onRequestFailed(throwable: Throwable) {
handleError(throwable)
}
})
}
TrueMoney Wallet
fun createTrueMoneySource(
amount: Long,
phoneNumber: String
) {
val request = Source.CreateSourceRequest(
amount = amount,
currency = "thb",
type = SourceType.TrueMoney,
phoneNumber = phoneNumber
)
client.send(request, sourceCallback)
}
// การใช้งาน
createTrueMoneySource(
amount = 100000L,
phoneNumber = "0812345678"
)
Alipay
fun createAlipaySource(amount: Long) {
val request = Source.CreateSourceRequest(
amount = amount,
currency = "thb",
type = SourceType.Alipay
)
client.send(request, sourceCallback)
}
คอมโพเนนต์ UI
ฟอร์มบัตรเครดิตที่สร้างไว้ในตัว
SDK ให้บริการ Activity ฟอร์มบัตรเครดิตที่สร้างไว้ล่วงหน้า:
import co.omise.android.ui.CreditCardActivity
class PaymentActivity : AppCompatActivity() {
private val creditCardLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == RESULT_OK) {
val token = result.data?.getParcelableExtra<Token>("token")
token?.let { handleToken(it) }
}
}
fun openCreditCardForm() {
val intent = Intent(this, CreditCardActivity::class.java).apply {
putExtra(CreditCardActivity.EXTRA_PKEY, "pkey_test_5xyzyx5xyzyx5xyzyx5")
putExtra(CreditCardActivity.EXTRA_AMOUNT, 100000L)
putExtra(CreditCardActivity.EXTRA_CURRENCY, "thb")
}
creditCardLauncher.launch(intent)
}
private fun handleToken(token: Token) {
Log.d("Payment", "Token received: ${token.id}")
sendTokenToServer(token.id)
}
}
ตัวเลือกวิธีการชำระเงิน
import co.omise.android.ui.PaymentMethodChooserActivity
class PaymentActivity : AppCompatActivity() {
private val paymentMethodLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
when (result.resultCode) {
RESULT_OK -> {
val token = result.data?.getParcelableExtra<Token>("token")
val source = result.data?.getParcelableExtra<Source>("source")
token?.let { handleToken(it) }
source?.let { handleSource(it) }
}
}
}
fun openPaymentMethodChooser() {
val intent = Intent(this, PaymentMethodChooserActivity::class.java).apply {
putExtra(PaymentMethodChooserActivity.EXTRA_PKEY, "pkey_test_5xyzyx5xyzyx5xyzyx5")
putExtra(PaymentMethodChooserActivity.EXTRA_AMOUNT, 100000L)
putExtra(PaymentMethodChooserActivity.EXTRA_CURRENCY, "thb")
}
paymentMethodLauncher.launch(intent)
}
}
ฟอร์มการชำระเงินที่กำหนดเองด้วย Jetpack Compose
import androidx.compose.runtime.*
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun PaymentForm(
viewModel: PaymentViewModel = viewModel()
) {
var cardNumber by remember { mutableStateOf("") }
var expiryDate by remember { mutableStateOf("") }
var cvv by remember { mutableStateOf("") }
var cardholderName by remember { mutableStateOf("") }
val isLoading by viewModel.isLoading.collectAsState()
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
OutlinedTextField(
value = cardNumber,
onValueChange = { cardNumber = it },
label = { Text("Card Number") },
placeholder = { Text("4242 4242 4242 4242") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(8.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
OutlinedTextField(
value = expiryDate,
onValueChange = { expiryDate = it },
label = { Text("Expiry") },
placeholder = { Text("MM/YY") },
modifier = Modifier.weight(1f)
)
OutlinedTextField(
value = cvv,
onValueChange = { cvv = it },
label = { Text("CVV") },
placeholder = { Text("123") },
modifier = Modifier.weight(1f)
)
}
Spacer(modifier = Modifier.height(8.dp))
OutlinedTextField(
value = cardholderName,
onValueChange = { cardholderName = it },
label = { Text("Cardholder Name") },
placeholder = { Text("John Doe") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = {
viewModel.createToken(
name = cardholderName,
number = cardNumber.replace(" ", ""),
expirationMonth = expiryDate.take(2).toIntOrNull() ?: 0,
expirationYear = 2000 + (expiryDate.takeLast(2).toIntOrNull() ?: 0),
securityCode = cvv
)
},
enabled = !isLoading,
modifier = Modifier.fillMaxWidth()
) {
if (isLoading) {
CircularProgressIndicator(
modifier = Modifier.size(24.dp),
color = MaterialTheme.colorScheme.onPrimary
)
} else {
Text("Pay Now")
}
}
}
}
การตรวจสอบความถูกต้องของข้อมูลนำเข้า
การตรวจสอบหมายเลขบัตร
import co.omise.android.util.CardValidator
import co.omise.android.models.CardBrand
// ตรวจสอบรูปแบบหมายเลขบัตร
val cardNumber = "4242424242424242"
val isValid = CardValidator.isValidCardNumber(cardNumber)
// ตรวจหายี่ห้อบัตร
val brand = CardValidator.getCardBrand(cardNumber)
when (brand) {
CardBrand.VISA -> println("บัตร Visa")
CardBrand.MASTERCARD -> println("Mastercard")
CardBrand.JCB -> println("บัตร JCB")
else -> println("ยี่ห้อไม่รู้จัก")
}
// จัดรูปแบบหมายเลขบัตรด้วยช่องว่าง
val formatted = CardValidator.formatCardNumber(cardNumber) // "4242 4242 4242 4242"