Manage PayPal QRC payments

The following describes how to work with QRC payments with the Android SDK. Operations include starting, processing, retrieving, and refunding.

Starting PayPal QRC payments

Start by creating a unique transaction reference string for each payment, which can be used to trace this payment in our system. Examples are provided in Kotlin.

Important: This unique reference string must be UTF-8 and up to 128 characters, otherwise payment will be denied.

1
val uiniqueReference = UUID.randomUUID().toString()

Then you need to start PayPalQrcPaymentActivity and use the IntentBuilder to inject the desired configuration for this payment.

1
val intent = PayPalQrcPaymentActivity.IntentBuilder(this)
2
// MANDATORY: Transaction amount in account currency
3
.amount(20000L)
4
// MANDATORY, Reference object created in previous step
5
.reference(uiniqueReference)
6
// OPTIONAL, Payment flow appearance - valid only for US market
7
.appearance(PayPalQrcType.PayPal)
8
.build()
9
10
// Start activity with the intent
11
startActivityForResult(intent, 0)

About appearance

When using PayPal QRC payments, merchants located in the US will have an option to start the payment using PayPal or Venmo UI appearances. This is because consumers can scan the QR code using either the Venmo or PayPal applications. In the payment result, you will be able to extract which payment method was used by the consumer.

Processing PayPal QRC payment results

You will receive the payment result as an Activity result. The result Bundle contains two values:

NameTypeDescription
PayPalQrcPaymentActivity.RESULT_EXTRA_REQUESTBundleThe extras bundle from request intent.
PayPalQrcPaymentActivity.RESULT_EXTRA_PAYLOADPayPalQrcPaymentResultThe payment result.

PayPalQrcPaymentResult

The payment result is an instance of one of the following classes described in the following:

  • PayPalQrcPaymentResult.Canceled
  • PayPalQrcPaymentResult.Failed
  • PayPalQrcPaymentResult.Completed

The PayPalQrcPaymentResult is a Kotlin sealed class, meaning it's always one of the following implementations.

NameDescription
PayPalQrcPaymentResult.CanceledPayment was canceled by merchant or customer. Doesn't contain any additional data.
PayPalQrcPaymentResult.FailedPayment failed. The failure reason is defined by the reason field.
PayPalQrcPaymentResult.CompletedPayPal QRC payment was successfully completed. Contains transaction info in the payload field.

The failed and completed results contain more detailed information regarding the failure reason, or the payload of the successful payment.

Extracting the failure reason

The PayPalQrcPaymentResult.Failed contains an instance of PayPalQrcPaymentFailureReason that describes the failure and can contain any of the following reasons.

NameDescription
PayPalQrcPaymentFailureReason.TimeoutPayment took too long to be completed
PayPalQrcPaymentFailureReason.TechnicalErrorPayment failed because of technical issues such as problems in the communication protocol.
PayPalQrcPaymentFailureReason.NetworkErrorCommunication with Zettle servers failed
PayPalQrcPaymentFailureReason.ActivationNotCompletedUser was not yet onborded to this payment method.
PayPalQrcPaymentFailureReason.SellerDataErrorFound some problems in the merchant information.
PayPalQrcPaymentFailureReason.FeatureNotEnabledCurrently logged-in user is not allowed to use this payment method, could be the case when merchant is not from one of the supported countries.
PayPalQrcPaymentFailureReason.AboveMaximumRequested amount is greater than account limit
PayPalQrcPaymentFailureReason.BellowMinimumRequested amount is smaller than allowed minimum

Extracting the success payload

A successful payment contains a payload of type PayPalQrcPayment with fields describing the payment as listed in the following.

NameTypeDescription
amountLongTotal transaction amount
typePayPalQrcTypeThe QRC flavor used to perform the payment - PayPal or Venmo (USA only)
referenceStringThe unique reference string provided when payment was started
referenceNumberString?Zettles reference to the payment
transactionIdString?The ID for the transaction in the Zettle system. The ID is automatically generated by the Zettle system.

Retrieving PayPal QRC payments

To retrieve a PayPal QRC payment you need to provide the same unique reference ID provided with the payment itself. See Starting PayPal QRC payments.

1
IZettleSDK.refundsManager.retrievePayPalQrc(activity, uniqueReference, object : RefundsManager.Callback<PayPalQrcPayment, RetrievePayPalQrcFailureReason> {
2
override fun onFailure(reason: RetrievePayPalQrcFailureReason) {/*...*/}
3
override fun onSuccess(payment: PayPalQrcPayment) {/*...*/}
4
})

Refunding PayPal QRC payments

A refund works similar to a payment with the exception that you need to provide the original payment when starting the refund. See Retrieving PayPal QRC payments.

When you have your payment object, you need to create a new unique transaction reference string for each refund. This reference string can be used to trace the refund in our system if needed.

1
val uniqueRefundReference = UUID.randomUUID().toString()

Important: This unique reference string must be UTF-8 and up to 128 characters, otherwise payment will be denied.

Next step is to start PayPalQrcPaymentActivity. Use the IntentBuilder to inject the desired configuration for this refund.

1
val intent = PayPalQrcRefundActivity.IntentBuilder(context)
2
// OPTIONAL: Refund amount in account currency
3
// This amount must be less or equal to the original card payment.
4
// If not provided it will use original card payment amount
5
// NOTE: if not provided, then it will perform a full refund.
6
.amount(20000L)
7
// Reference object created in previous step
8
.reference(uniqueRefundReference)
9
// Unique reference for the payment that you want to perform refund.
10
.paymentReference(paymentUniqueRerence)
11
.build()
12
13
// Start activity with the intent
14
startActivityForResult(intent, 0)

Processing PayPal QRC refund results

You will receive the refund result as an Activity result. The result Bundle contains two values:

NameTypeDescription
PayPalQrcRefundActivity.RESULT_EXTRA_REQUESTBundleThe extras bundle from request intent.
PayPalQrcRefundActivity.RESULT_EXTRA_PAYLOADPayPalQrcRefundResultThe refund result.

PayPalQrcRefundResult

The refund result is an instance of one of the following classes:

  • PayPalQrcRefundResult.Canceled
  • PayPalQrcRefundResult.Failed
  • PayPalQrcRefundResult.Completed

The PayPalQrcRefundResult is a Kotlin sealed class, meaning it's always one of the following implementations.

NameDescription
PayPalQrcRefundResult.CanceledRefund was canceled by merchant or customer. Doesn't contain any additional data.
PayPalQrcRefundResult.FailedRefund failed. The failure reason is defined by the reason field.
PayPalQrcRefundResult.CompletedRefund was successfully completed. Contains transaction info in the payload field.

The failed and completed results contain more detailed information regarding the failure reason, or the payload of a successful refund.

Extracting the failure reason

The PayPalQrcRefundResult.Failed contains an instance of PayPalQrcPaymentFailureReason that describes the failure and can contain any of the following reasons.

NameDescription
PayPalQrcPaymentFailureReason.NotAuthenticatedAuthentication flow was cancelled or interrupted
PayPalQrcPaymentFailureReason.NotAuthorizedThere is no authorised user to process payment request
PayPalQrcPaymentFailureReason.AlreadyRefundedPayment was already refunded
PayPalQrcPaymentFailureReason.NotFoundPayment with given reference ID was not found
PayPalQrcPaymentFailureReason.AmountTooHighTrying to perform refund with amount higher than original payment
PayPalQrcPaymentFailureReason.PartialRefundNotSupportedPartial refund is not allowed for this payment
PayPalQrcPaymentFailureReason.InsufficientFundsAccount does not have sufficient funds to perform refund
PayPalQrcPaymentFailureReason.RefundExpiredPayment refund is too old to be refunded
PayPalQrcPaymentFailureReason.TechnicalErrorPayment failed because of technical issues
PayPalQrcPaymentFailureReason.NetworkErrorCommunication with Zettle servers failed
PayPalQrcPaymentFailureReason.FailedFailure due to unknown reasons

Extracting the success payload

A successful refund contains a payload of type PayPalQrcRefund with fields describing the refund as listed in the following.

NameTypeDescription
amountLongTotal refund amount
originalAmountLong?Contains the original payment amount
referenceStringThe unique reference string provided when refund was started
referenceNumberString?Zettles reference to the payment.
transactionIdString?The ID for the transaction in the Zettle system. The ID is automatically generated by the Zettle system.

PayPal QRC activation

To start taking PayPal QRC payments, users must first read and promptly accept the terms and conditions from the settings screen.

1
val intent = PayPalQrcActivationActivity.IntentBuilder(context).build()
2
startActivity(intent)

Testing payment and refund

When integrating with the SDK, you can test your integration in developer mode for PayPal and Venmo QRC without a Zettle merchant account and real transactions.

  1. If developer mode is not enabled, enable it by calling the following function in your integration project:

    1
    IZettleSDK.init(
    2
    ...,
    3
    isDevMode = true
    4
    )
  2. Launch the payment flow.

  3. Check the responses.

    The example shows test case "Successfully paid with PayPal".

    1
    "payment": {
    2
    "type": "PayPal",
    3
    "transactionId": "3702b69c-5b53-11ed-bb53-e32a574ae480",
    4
    "referenceNumber": "5RD45483J23141148",
    5
    "amount": <the payment amount passed to the SDK>,
    6
    "reference": "<the reference passed to the SDK>"
    7
    }
  4. Launch the refund flow.

  5. Check the responses.

    The example shows test case "Successful PayPal refund".

    1
    "payload": {
    2
    "transactionId": "c1ee606d-5b54-11ed-8c7e-9873cea95625",
    3
    "referenceNumber": "6VE826082H938612A",
    4
    "amount": <the refund amount passed to the SDK>,
    5
    "originalAmount": 1000,
    6
    "type": "PayPal",
    7
    "reference": "<the reference passed to the SDK>"
    8
    }