Skip to main content

Overview

Pay With PayMaya provides two payment flows:
  1. Single Payment - One-time payment using a PayMaya wallet
  2. Wallet Link - Create a wallet link for recurring payments (charge a PayMaya account later)
Both flows use a secure WebView where customers authenticate and authorize payments.

Client Initialization

Initialize the Pay With PayMaya client with your API credentials:
val payWithPayMayaClient = PayWithPayMaya.newBuilder()
    .clientPublicKey("pk-test-your-public-key")
    .environment(PayMayaEnvironment.SANDBOX)
    .logLevel(LogLevel.ERROR)
    .build()

Builder Methods

MethodRequiredDescription
clientPublicKey(String)YesYour PayMaya client public key
environment(PayMayaEnvironment)YesSANDBOX or PRODUCTION
logLevel(LogLevel)NoConsole logging level (VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT)

Single Payment

Single Payment allows customers to make a one-time payment using their PayMaya wallet.

Flow Steps

1

Create Single Payment Request

Build a SinglePaymentRequest with payment amount and redirect URLs.
2

Start Payment Activity

Launch the payment activity where customers authenticate with their PayMaya wallet.
3

Handle Result

Process the payment result to determine success, cancellation, or failure.

Creating a Single Payment Request

// Define the payment amount
val totalAmount = TotalAmount(
    value = BigDecimal("250.00"),
    currency = "PHP"
)

// Define redirect URLs
val redirectUrl = RedirectUrl(
    success = "https://yourapp.com/success",
    failure = "https://yourapp.com/failure",
    cancel = "https://yourapp.com/cancel"
)

// Create the single payment request
val request = SinglePaymentRequest(
    totalAmount = totalAmount,
    requestReferenceNumber = "PAYMENT-${System.currentTimeMillis()}",
    redirectUrl = redirectUrl,
    metadata = JSONObject().apply {
        put("orderId", "12345")
        put("customerId", "user-67890")
    }
)

SinglePaymentRequest Properties

PropertyTypeRequiredDescription
totalAmountTotalAmountYesTransaction amount details
requestReferenceNumberStringYesMerchant’s reference number for the transaction
redirectUrlRedirectUrlYesURLs for success, failure, and cancel scenarios
metadataJSONObjectNoAdditional custom data

Starting Single Payment

Launch the single payment activity:
payWithPayMayaClient.startSinglePaymentActivityForResult(this, request)

Handling Single Payment Results

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    
    payWithPayMayaClient.onActivityResult(requestCode, resultCode, data)?.let { result ->
        when (result) {
            is SinglePaymentResult.Success -> {
                val message = "Payment successful! Payment ID: ${result.paymentId}"
                Toast.makeText(this, message, Toast.LENGTH_LONG).show()
                // Process successful payment
            }
            
            is SinglePaymentResult.Cancel -> {
                val message = "Payment canceled. Payment ID: ${result.paymentId}"
                Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
                // Handle cancellation
            }
            
            is SinglePaymentResult.Failure -> {
                val message = "Payment failed: ${result.exception.message}"
                Toast.makeText(this, message, Toast.LENGTH_LONG).show()
                // Handle failure
            }
        }
    }
}

SinglePaymentResult Types

SinglePaymentResult.Success
PropertyTypeDescription
paymentIdStringPayment identifier for the transaction
SinglePaymentResult.Cancel
PropertyTypeDescription
paymentIdString?Payment identifier if available, null otherwise
SinglePaymentResult.Failure
PropertyTypeDescription
paymentIdString?Payment identifier if available, null otherwise
exceptionExceptionException with detailed reason for the failure
If the user closes the activity (e.g., by pressing Back button), the SDK automatically checks payment status if paymentId has been retrieved:
  • PAYMENT_SUCCESSSinglePaymentResult.Success
  • AUTH_FAILED or PAYMENT_FAILEDSinglePaymentResult.Failure
  • Otherwise → SinglePaymentResult.Cancel
Wallet Link creates a link to a PayMaya wallet that allows you to charge the account later for recurring payments.

Flow Steps

1

Create Wallet Link Request

Build a CreateWalletLinkRequest with your reference number and redirect URLs.
2

Start Wallet Link Activity

Launch the activity where customers link their PayMaya wallet.
3

Handle Result

Receive the linkId which can be used for future charges.
// Define redirect URLs
val redirectUrl = RedirectUrl(
    success = "https://yourapp.com/success",
    failure = "https://yourapp.com/failure",
    cancel = "https://yourapp.com/cancel"
)

// Create the wallet link request
val request = CreateWalletLinkRequest(
    requestReferenceNumber = "LINK-${System.currentTimeMillis()}",
    redirectUrl = redirectUrl,
    metadata = JSONObject().apply {
        put("customerId", "user-67890")
        put("subscriptionPlan", "premium")
    }
)

CreateWalletLinkRequest Properties

PropertyTypeRequiredDescription
requestReferenceNumberStringYesMerchant’s reference number for the wallet link
redirectUrlRedirectUrlYesURLs for success, failure, and cancel scenarios
metadataJSONObjectNoAdditional custom data
Launch the wallet link activity:
payWithPayMayaClient.startCreateWalletLinkActivityForResult(this, request)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    
    payWithPayMayaClient.onActivityResult(requestCode, resultCode, data)?.let { result ->
        when (result) {
            is CreateWalletLinkResult.Success -> {
                val message = "Wallet linked successfully! Link ID: ${result.linkId}"
                Toast.makeText(this, message, Toast.LENGTH_LONG).show()
                // Store linkId for future recurring charges
                saveWalletLinkId(result.linkId)
            }
            
            is CreateWalletLinkResult.Cancel -> {
                val message = "Wallet linking canceled"
                Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
                // Handle cancellation
            }
            
            is CreateWalletLinkResult.Failure -> {
                val message = "Wallet linking failed: ${result.exception.message}"
                Toast.makeText(this, message, Toast.LENGTH_LONG).show()
                // Handle failure
            }
        }
    }
}

CreateWalletLinkResult Types

CreateWalletLinkResult.Success
PropertyTypeDescription
linkIdStringWallet link identifier for future recurring charges
CreateWalletLinkResult.Cancel
PropertyTypeDescription
linkIdString?Wallet link identifier if available, null otherwise
CreateWalletLinkResult.Failure
PropertyTypeDescription
linkIdString?Wallet link identifier if available, null otherwise
exceptionExceptionException with detailed reason for the failure
The linkId returned from a successful wallet link creation can be used on your backend to charge the customer’s PayMaya wallet for recurring payments.

Checking Payment Status

Manually verify the status of a payment:
// This method is synchronous - call from a background thread
lifecycleScope.launch(Dispatchers.IO) {
    val status = payWithPayMayaClient.checkPaymentStatus(paymentId)
    
    withContext(Dispatchers.Main) {
        when (status) {
            is CheckPaymentStatusResult.Success -> {
                Log.d(TAG, "Payment status: ${status.paymentStatus}")
            }
            is CheckPaymentStatusResult.Failure -> {
                Log.e(TAG, "Status check failed: ${status.exception}")
            }
        }
    }
}
The checkPaymentStatus method is synchronous. Always call it from a background thread.

Testing

For the Sandbox environment, use the test credentials provided in the PayMaya documentation.

Complete Examples

Single Payment Example

class SinglePaymentActivity : AppCompatActivity() {
    
    private lateinit var payWithPayMayaClient: PayWithPayMaya
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_single_payment)
        
        // Initialize client
        payWithPayMayaClient = PayWithPayMaya.newBuilder()
            .clientPublicKey("pk-test-your-public-key")
            .environment(PayMayaEnvironment.SANDBOX)
            .logLevel(LogLevel.ERROR)
            .build()
        
        findViewById<Button>(R.id.btnPay).setOnClickListener {
            startSinglePayment()
        }
    }
    
    private fun startSinglePayment() {
        val request = SinglePaymentRequest(
            totalAmount = TotalAmount(
                value = BigDecimal("250.00"),
                currency = "PHP"
            ),
            requestReferenceNumber = "PAYMENT-${System.currentTimeMillis()}",
            redirectUrl = RedirectUrl(
                success = "https://yourapp.com/success",
                failure = "https://yourapp.com/failure",
                cancel = "https://yourapp.com/cancel"
            )
        )
        
        payWithPayMayaClient.startSinglePaymentActivityForResult(this, request)
    }
    
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        
        payWithPayMayaClient.onActivityResult(requestCode, resultCode, data)?.let { result ->
            when (result) {
                is SinglePaymentResult.Success -> {
                    Toast.makeText(this, "Payment Successful!", Toast.LENGTH_LONG).show()
                }
                is SinglePaymentResult.Cancel -> {
                    Toast.makeText(this, "Payment Canceled", Toast.LENGTH_SHORT).show()
                }
                is SinglePaymentResult.Failure -> {
                    Toast.makeText(this, "Payment Failed", Toast.LENGTH_LONG).show()
                }
            }
        }
    }
}
class WalletLinkActivity : AppCompatActivity() {
    
    private lateinit var payWithPayMayaClient: PayWithPayMaya
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_wallet_link)
        
        // Initialize client
        payWithPayMayaClient = PayWithPayMaya.newBuilder()
            .clientPublicKey("pk-test-your-public-key")
            .environment(PayMayaEnvironment.SANDBOX)
            .logLevel(LogLevel.ERROR)
            .build()
        
        findViewById<Button>(R.id.btnLinkWallet).setOnClickListener {
            startWalletLinking()
        }
    }
    
    private fun startWalletLinking() {
        val request = CreateWalletLinkRequest(
            requestReferenceNumber = "LINK-${System.currentTimeMillis()}",
            redirectUrl = RedirectUrl(
                success = "https://yourapp.com/success",
                failure = "https://yourapp.com/failure",
                cancel = "https://yourapp.com/cancel"
            )
        )
        
        payWithPayMayaClient.startCreateWalletLinkActivityForResult(this, request)
    }
    
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        
        payWithPayMayaClient.onActivityResult(requestCode, resultCode, data)?.let { result ->
            when (result) {
                is CreateWalletLinkResult.Success -> {
                    // Save linkId for future recurring charges
                    val linkId = result.linkId
                    Toast.makeText(this, "Wallet Linked: $linkId", Toast.LENGTH_LONG).show()
                }
                is CreateWalletLinkResult.Cancel -> {
                    Toast.makeText(this, "Wallet Linking Canceled", Toast.LENGTH_SHORT).show()
                }
                is CreateWalletLinkResult.Failure -> {
                    Toast.makeText(this, "Wallet Linking Failed", Toast.LENGTH_LONG).show()
                }
            }
        }
    }
}

Build docs developers (and LLMs) love