PayPal In-Store
PXP Financial are partnering with PayPal and support PayPal's In-Store QR-Code based payment solution.
There are two available flows for PayPal’s in-store QR code payments:
- Consumer-presented, in which the customers PayPal app displays a barcode to be scanned by the
POS. - Merchant-presented, in which the merchant POS displays a QR code to be scanned by the customer using the PayPal app.
The following method IDs are covered in this section:
ID | Name | Credit/Debit State | Flow |
---|---|---|---|
427 | PayPal User Initiated POS Deposit | DepositedByProvider (29) | Consumer Presented |
426 | PayPal Merchant Initiated POS Deposit | DepositedByProvider (29) | Merchant Presented |
Consumer Presented vs. Merchant Presented Flow
Consumer-presented QR code use case
- User shops in a retail store and brings items to the POS for checkout.
- When prompted, the user indicates they want to pay with PayPal. The user opens the PayPal app on the mobile and displays a QR code.
- The POS scans the QR code and passes the value to the PXP System using payment method ID
427
PayPal User Initiated POS Deposit
- PXP system parses the QR code value and calls PayPal’s API, which returns a reference ID and indicates that the
consumer needs to approve the transaction on their phone. - Once the user confirms the purchase, the payment is completed.
- Depending on the user’s individual settings, they may receive a notification (push, SMS, email)
from PayPal indicating that the account was charged. - The user collects the POS receipt and exits the store with the purchased goods.
Sequence Diagram:
Merchant-presented flow
In the merchant-presented flow, the transaction starts by the POS generating and displaying a QR code,
which is scanned by the PayPal app. After that, the user experience is identical to that of the
consumer-presented flow.
Sequence Diagram:
Merchant and Site Onboarding
Merchant Account Onboarding
PXP has a partner integration with PayPal to offer PayPal In-Store to the merchants. PXP acts as the API caller for the merchant. The merchant needs to have a PayPal business account (with a confirmed/validated email address) and will receive the money directly via PayPal on his Paypal account.
Before a merchant can start processing PayPal In-Store transactions via PXP, merchants need to grant permission to PXP to process PayPal Transactions for them using a predefined onboarding process. This will be done together with the merchant during the test setup for PayPal In-Store. The PXP support team will guide the merchant through this exercise.
Merchant Business Onboarding for Marketing
After adding a merchant via the referral process (see above), PXP is obliged to onboard each merchant with the valid logo URI and the Merchant Business Name for marketing purposes with PayPal.
This information is needed from the merchant:
- id: The publicly visible label of this location. Max Length: 64
- business name: The business name of the party, this will be used as default merchant name
for branding. Max Length: 300 - logo url: (optional) The url of the logo of the merchant. It is also possible that PayPal hosts the logo.
If this information is not passed to Paypal, only the Merchant’s Business Name will be
shown on the buyers PayPal App screen during transaction approval.
PayPal recommends:
• Smallest size: 100x100 px saved at 1x, 2x, and 3x (high res)
• Logo centered with a 15 px margin all around, so that the logo will
sit in the whitespace at approximately 70px.
• The file should be of type .png
Format: URI - country_code: The two-character ISO 3166-1 code that identifies the country or region.
Note from Paypal: The country code for Great Britain is GB and not UK as used in the top-level domain names for that country. Use theC2
country code for China worldwide for comparable uncontrolled price (CUP) method, bank card, and cross-border transactions.
Onboarding Locations
In order for PayPal to accept in-store payments, PXP must onboard each merchant’s store
locations with PayPal.
The below information has to be provided for each location:
- name: The publicly visible label of this location. Max Length: 128
- internalName: A merchant-assigned internal name of this location. This will be used as part of the soft descriptor by Networks (Visa, Mastercard etc.) to present in the bank statement. Max Length: 64
- mobility: The mobile setting for this location. Enum: mobile, fixed, Recommended value: “fixed”
- phoneNumber (optional): The phone number for this location. Max Length: 40
- address: address line 1, addres line 2 (optional), city, state, country, postalCode
- latitude: The latitude of this location. Max Length: 200
Location data will be utilized for enhanced Risk assessment capabilities and proximity alerts for marketing purposes by Paypal. - longitude: The longitude of this location. Max Length: 200
- tabType: The type of tab supported at this location. Enum: standard, none; Recommended value: "none"
- availability: Whether this location is currently open for business. Enum: open, closed
This value does not affect the payment authorization. Recommended value: “open”. - gratuityType: The type of gratuity that is accepted by this location. Enum: standard, none; Recommended value: “none”
Example:
"name": "Jewelry Loc 1",
"internalName": "Jewelery San Jose",
"mobility": "fixed",
"phoneNumber": "408-967-9174",
"address": {
"line1": "2212 N First Street",
"city": "San Jose",
"state": "CA",
"postalCode": "95131",
"country": "US"
},
"latitude": 49.265,
"longitude": -125.569,
"tabType": "none",
"availability": "closed",
"gratuityType": "STANDARD"
Backend2Backend Integration - Consumer Presented Flow
Payment Method ID covered in this section:
ID | Name |
---|---|
427 | PayPal User Initiated POS Deposit |
Preconditions:
- Customer is at the counter in the store and wants to pay with PayPal
- Merchant wants to use the Consumer Presented Flow
Step 1: Merchant POS to scan the QR code from the consumers PayPal App
Merchant should ask the customer to open his Paypal App on his mobile and create a QR code.
Then the merchant has to scan this QR code.
QR Code Refresh and Time-to-Live
The PayPal QR codes are dynamic, one-time-use tokens with a limited time-to-live (TTL).
For the consumer-presented QRC flow, the PayPal app display each QR code for 1 minute
before the screen refreshes automatically and generates a new code.
Once a QR code is scanned and submitted to Paypal (via PXP gateway), the transaction must be
completed within 50 seconds or else PayPal will time out the transaction.
Step 2: Payment Initiation
After the merchant POS has scanned the QR code presented by the consumer, the merchant has to call the PXP API with the below mentioned additional information.
Only accept PayPal QR Code
The merchant should only initiate the payment with PXP if the QR code is a "PayPal-code".
The QR code format will start with “79” for PayPal. If the QR code does not start with "79", then it must not be sent to PXP. (e.g. “89” would be for Venmo).
The following parameters have to be provided in initiatePaymentRequest.specificPaymentData
:
key (value type, account type, required) | value |
---|---|
CustomerQRcode (string, required) | The code of the scanned QR code which was presented by the Customer in his PayPal App. Example: 791020281849 |
PaymentDescription (string) | Must be set to Merchant’s name. Used as transaction invoice soft_descriptor in the capture request to PayPal. PayPal uses the value of this field for constructing the merchant’s description in the customer’s credit card statement This field is used for branding in the Paypal receipt. Also used to construct the merchant’s description in the customer’s credit card statement: Ex: “PAYPAL *<soft_descriptor> ” where Store Id is the name of the store as it was defined when onboarding the merchant location with PayPal (in the setup process) |
Example initiatePaymentRequest
for a successful payment
<?xml version="1.0" encoding="UTF-8"?>
<initiatePaymentRequest xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<merchantID>B2BTestMerchant</merchantID>
<shopID>IrisMockShop</shopID>
<merchantTransactionID>{{$guid}}</merchantTransactionID>
<paymentMethodID>63</paymentMethodID>
<amount currencyCode="USD">16.5</amount>
<userID>{{$guid}}</userID>
<userData>
<username>johndoe</username>
<firstname>John</firstname>
<lastname>Doe</lastname>
</userData>
<userIP>127.0.0.1</userIP>
<userSessionID>6013e9af-89b6-4fc3-8f47-0d78264038b2</userSessionID>
<creationTypeID>12</creationTypeID>
<specificPaymentData>
<data xsi:type="keyStringValuePair">
<key>PaymentDescription</key>
<value>QRCode deposit</value>
</data>
<data xsi:type="keyIntValuePair">
<key>PaymentProviderID</key>
<value>56</value>
</data>
<data xsi:type="keyStringValuePair">
<key>CustomerQRcode</key>
<value>791020281849</value>
</data>
</specificPaymentData>
</initiatePaymentRequest>
Step 3: PayPal asks Customer to confirm
After the merchant has sent the initiatePaymentRequest
to PXP, PXP sends a capture request to PayPal.
If that is successful, PayPal then asks the customer to approve the payment in the PayPal App.
If that is not successful, PXP will respond with an error state, see possible states in Step4 below.
QuickPay
In the consumer presented flow, PayPal has "QuickPay" enabled by default, which means that the Customer approval in Step 3 is not applicable and auto-approved.
Step 4: PXP to send Payment Initiation Response
After the customer has approved the payment, PXP system will query the PayPal System for the success status (or failure status) and return the synchronous response to the initiatePaymentRequest
.
Example initiatePaymentResponse
for a successful payment
<initiatePaymentResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<payment xsi:type="paymentWithPaymentAccount">
<merchantID>B2BTestMerchant</merchantID>
<shopID>IrisMockShop</shopID>
<paymentMethod>
<key>427</key>
<value>PayPal User Initiated POS Deposit</value>
</paymentMethod>
<merchantTransactionID>5285b3f2-c8ea-4864-a109-bffd45a63e9a</merchantTransactionID>
<paymentID>a0c4cf91-f0e5-4c36-b6f6-4520f1cae4e1</paymentID>
<userID>c137af64-72b7-49a1-8ef8-05236cd0397f</userID>
<paymentProvider>
<key>56</key>
<value>PayPal</value>
</paymentProvider>
<amount currencyCode="USD">16.5</amount>
<creationType>
<key>12</key>
<value>POS</value>
</creationType>
<userIP>127.0.0.1</userIP>
<state>
<id>c6e6e7be-4279-42ad-bfd0-b4cb3743327a</id>
<definition>
<key>29</key>
<value>DepositedByProvider</value>
</definition>
<createdOn>2021-09-22T09:29:45.2955844Z</createdOn>
<paymentStateDetails xsi:nil="true"></paymentStateDetails>
</state>
<isExecuted>true</isExecuted>
<baseAmount currencyCode="EUR">12.4</baseAmount>
<paymentDetails>
<detail xsi:type="keyStringValuePair">
<key>ProviderTransactionID</key>
<value>3ba7d6da-35d0-42ff-a5bf-31064a5b6592</value>
</detail>
<detail xsi:type="keyStringValuePair">
<key>ProviderExternalID</key>
<value>38063311</value>
</detail>
</paymentDetails>
<paymentAccount>
<paymentAccountID>6bab8749-7d7c-4282-b2ec-1b1b77c26f71</paymentAccountID>
</paymentAccount>
</payment>
</initiatePaymentResponse>
Possible payment states in initiatePaymentResponse:
Payment State | Description | What to do |
---|---|---|
DepositedByProvider | ID = 29 Success state | Print receipt |
RefusedByProvider | Error state, Refused by Provider | |
AbortedByProvider | Error state | |
AbortedByCustomer | Error state | |
InitiateRequestProviderCommunicationErrorOccurred | PXP Capture request to PayPal failed due to a communication error | Payment not successful, ask Customer to try again or choose other payment method |
QueryPaymentStateCommunicationErrorOccured | PXP request to query for the payment state in the PayPal system failed due to a communication error | Payment not successful, ask Customer to try again or choose other payment method |
QueryPaymentStateErrorReportedByProvider | PXP request to query for the payment state in the PayPal system failed due to an unknown error at PayPal side | Payment not successful, ask customer to choose other payment method |
Timeout
If the initiatePayment request failed due to a time out, merchant should use
https://developer.kalixa.com/reference/getpayments
to get the status of the payment and see if the payment was successful
if not, merchant can trigger the scanning of the qr code again.
Step 5: Notifications
The standard notification mechanism is used for notifying the merchant in the background (asynchronously) about payment state changes. For more information see PaymentStateChangedNotification.
In case the payment initiation with PayPal has failed due to communication errors (see step 4), PXP will automatically cancel the payment with PayPal and notify the merchant about the Cancellation.
Example handlePaymentStateChangedNotification
:
<?xml version="1.0" encoding="utf-8"?>
<handlePaymentStateChangedNotificationRequest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.cqrpayments.com/PaymentProcessing">
<payment xsi:type="paymentWithPaymentAccount">
<merchantID>B2BTestMerchant</merchantID>
<shopID>IrisMockShop</shopID>
<paymentMethod>
<key>63</key>
<value>PayPalDeposit</value>
</paymentMethod>
<merchantTransactionID>6f651a86-9005-414c-9096-ca7fc4dd2dad</merchantTransactionID>
<paymentID>826c7106-5238-4d5a-85dd-119fe7bab66b</paymentID>
<userID>zc1544de-7443-45f6-976e-d253c2</userID>
<paymentProvider>
<key>56</key>
<value>PayPal</value>
</paymentProvider>
<amount currencyCode="USD">1.0000</amount>
<creationType>
<key>12</key>
<value>POS</value>
</creationType>
<userIP>127.0.0.1</userIP>
<state>
<id>400eaecb-89ef-489b-9683-4fa8a9b922b0</id>
<definition>
<key>113</key>
<value>Cancelled</value>
</definition>
<createdOn>2021-09-22T05:45:59.807</createdOn>
<paymentStateDetails xsi:nil="true" />
</state>
<isExecuted>true</isExecuted>
<baseAmount currencyCode="EUR">0.6600</baseAmount>
<paymentDetails>
<detail xsi:type="keyStringValuePair">
<key>ProviderExternalID</key>
<value>38062121</value>
</detail>
<detail xsi:type="keyIntValuePair">
<key>MerchantSettlementCurrencyID</key>
<value>2</value>
</detail>
<detail xsi:type="keyStringValuePair">
<key>ProviderTransactionID</key>
<value>d768f80e-a136-4e15-8382-ebe04f548eb5</value>
</detail>
</paymentDetails>
<paymentAccount>
<paymentAccountID>53db5a8e-a0e1-4a13-8251-af94959b3873</paymentAccountID>
</paymentAccount>
</payment>
</handlePaymentStateChangedNotificationRequest>
State Diagram for the Consumer Presented Flow
The following diagram shows the state flow of a 427
PayPal User Initiated POS Deposit
in the PXP System:
Backend2Backend Integration - Merchant Presented Flow
Payment Method ID covered in this section:
ID | Name |
---|---|
246 | PayPal Merchant Initiated POS Deposit |
Preconditions:
- Customer is at the counter in the store and wants to pay with PayPal
- Merchant wants to use the Merchant Presented Flow
Step 1: Call PXP to retrieve the QR code
QR Code Validity
If a QR code was already generated but not yet scanned by the merchant POS, it will remain valid for up to 15 minutes.
The following parameters have to be provided in initiatePaymentRequest.specificPaymentData
:
key | value |
---|---|
PaymentDescription (string) | Must be set to Merchant’s name. Used as transaction invoice soft_descriptor in the capture request to PayPal. PayPal uses the value of this field for constructing the merchant’s description in the customer’s credit card statement This field is used for branding in the Paypal receipt. Also used to construct the merchant’s description in the customer’s credit card statement: Ex: “PAYPAL *<soft_descriptor> ” where Store Id is the name of the store as it was defined when onboarding the merchant location with PayPal (in the setup process) |
Example initiatePaymentRequest
to receive the QR code
<?xml version="1.0" encoding="UTF-8"?>
<initiatePaymentRequest xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<merchantID>B2BTestMerchant</merchantID>
<shopID>IrisMockShop</shopID>
<merchantTransactionID>{{$guid}}</merchantTransactionID>
<paymentMethodID>426</paymentMethodID>
<amount currencyCode="USD">16.5</amount>
<userID>{{$guid}}</userID>
<userData>
<username>johndoe</username>
<firstname>John</firstname>
<lastname>Doe</lastname>
</userData>
<userIP>127.0.0.1</userIP>
<userSessionID>6013e9af-89b6-4fc3-8f47-0d78264038b2</userSessionID>
<creationTypeID>12</creationTypeID>
<specificPaymentData>
<data xsi:type="keyStringValuePair">
<key>PaymentDescription</key>
<value>QRCode deposit</value>
</data>
<data xsi:type="keyIntValuePair">
<key>PaymentProviderID</key>
<value>56</value>
</data>
</specificPaymentData>
</initiatePaymentRequest>
Example initiatePaymentResponse
(success case) to receive the QR code
<initiatePaymentResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<payment xsi:type="paymentWithPaymentAccount">
<merchantID>B2BTestMerchant</merchantID>
<shopID>IrisMockShop</shopID>
<paymentMethod>
<key>426</key>
<value>PayPal Merchant Initiated POS Deposit</value>
</paymentMethod>
<merchantTransactionID>emma_testing_00001</merchantTransactionID>
<paymentID>6756c158-ee1e-40f1-b613-18dc817cb244</paymentID>
<userID>82937a69-ff7e-4ec3-8985-56f221659e87</userID>
<paymentProvider>
<key>56</key>
<value>PayPal</value>
</paymentProvider>
<amount currencyCode="USD">16.5</amount>
<creationType>
<key>12</key>
<value>POS</value>
</creationType>
<userIP>127.0.0.1</userIP>
<state>
<id>80ea0fb3-ae1b-42a2-8b4c-9b0c7df74e65</id>
<definition>
<key>612</key>
<value>PendingOnConfirmation</value>
</definition>
<createdOn>2021-12-08T07:26:47.1896733Z</createdOn>
<paymentStateDetails xsi:nil="true"></paymentStateDetails>
</state>
<isExecuted>true</isExecuted>
<baseAmount currencyCode="EUR">10.96</baseAmount>
<paymentDetails>
<detail xsi:type="keyStringValuePair">
<key>QRCodeData</key>
<value>https://www.paypal.com/qrcodes/integrated?payer_id=UMU2UCQWS123Q&merchant_ref_id=39241301&time_stamp=1638954227</value>
</detail>
<detail xsi:type="keyStringValuePair">
<key>ProviderTransactionID</key>
<value>8ba39a08-165b-46df-9ad6-b52cf86598ad</value>
</detail>
<detail xsi:type="keyStringValuePair">
<key>ProviderExternalID</key>
<value>39240296</value>
</detail>
</paymentDetails>
<paymentAccount>
<paymentAccountID>3ddb4e8f-e70b-42f7-ad22-962aec9830a0</paymentAccountID>
</paymentAccount>
</payment>
</initiatePaymentResponse>
important Parameters in the response
Key | Details | Example |
---|---|---|
paymentDetails.QRCodeData | Contains the data to generate the QR code on the POS | https://www.paypal.com/qrcodes/integrated?payer_id=UMU2UCQWS123Q&merchant_ref_id=39241301&time_stamp=1638954227 |
state.definition | 612 PendingOnConfirmation | |
paymentID | The ID of the payment, to be stored and used for follow-up transactions like refunds. | 6756c158-ee1e-40f1-b613-18dc817cb244 |
Timeout
If the initiatePayment request failed due to a time out, retry mechanism not possible using
https://developer.kalixa.com/reference/getpayments
to get the status of the payment and to get QR code, this is not yet offered by PXP
Instead, merchant should start the request again.
Step 2: Present the QR code to the customer
The POS has to present the QR code.
Step 3: Customer to scan the QR code with PayPal App
Cashier to ask the customer to scan the QR code with his Paypal App.
PayPal App has to be used
The customer has to use the PayPal App (and not Venmo for example, which is also powered by PayPal), otherwise the payment would fail at a later stage.
PXP Financial only supports PayPal In-store at the time being.
Doing this will trigger the following actions which are handled between PayPal and PXP systems:
- PayPal notifies the PXP of the scan
- PXP triggers the payment creation with PayPal
- PayPal asks the customer for confirmation in the App
Step 4: Customer to approve the payment in the PaypPal App
The customer now has to approve the payment by confirming the PayPal prompt in the Paypal app.
Time Limit: 50 seconds
If the customer does not approve the payment in his App within 50 seconds, the session will time out (error: buyer confirmation not received).
In that case, the flow would need to be started over because the consumer would get an error when they try to advance and so they’d be taken back to the scan screen.
The customer approval triggers the completion of the payment in the PayPal system.
Step 5: Merchant send execute request
Now the merchant POS system has to send an executePaymentAction request containing the following data:
key | value |
---|---|
paymentID | The paymentID as received in the initiatePaymentResponse |
actionID | with value 39 QueryPaymentStateAtProvider |
Example executePaymentRequest
:
<?xml version="1.0" encoding="utf-8"?>
<executePaymentActionRequest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.cqrpayments.com/PaymentProcessing">
<merchantID>B2BTestMerchant</merchantID>
<shopID>IrisMockShop</shopID>
<paymentID>6756c158-ee1e-40f1-b613-18dc817cb244</paymentID>
<actionID>39</actionID>
</executePaymentActionRequest>
Based on this request, PXP system will start pulling information about the success of the transaction from Paypal and respond to the executePaymentRequest
.
Example executePaymentResponse
:
<executePaymentActionResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<statusCode>0</statusCode>
<actionResults>
<result xsi:type="keyStringValuePair">
<key>lastStateDefinition</key>
<value>29</value>
</result>
<result xsi:type="keyStringValuePair">
<key>QRCodeData</key>
<value>https://www.paypal.com/qrcodes/integrated?payer_id=UMU2UCQWS123Q&merchant_ref_id=39241422&time_stamp=1638959848</value>
<result xsi:type="keyStringValuePair">
<key>ProviderTransactionID</key>
<value>563c593f-820e-4553-918c-4b89a2dd0a52</value>
</result>
</actionResults>
</executePaymentActionResponse>
parameter | value | What it means |
---|---|---|
statusCode | 0 if executeAction request was successful anything else than 0 if action was not executed successfully by PXP | |
lastStateDefinition | 29 = DepositedByProvider | success case continue |
lastStateDefinition | RefusedByProvider AbortedByProvider AbortedByCustomer InitiateRequestProviderCommunicationErrorOccurred QueryPaymentStateErrorReportedByProvider InitiateErrorReportedByProvider | error cases, do not continue |
Step6: Merchant POS to display the success message and print receipt
If the executePaymentAction request was successful, the merchant POS should to display the success message to the cashier and print receipt.
The customer will also see a success message in the app displayed by PayPal.
State Diagram for the Merchant Presented Flow
The following diagram shows the state flow of a 426
PayPal Merchant Initiated POS Deposit
PayPal Merchant Initiated POS Deposit (426) in the PXP System:
Receipts
PayPal recommends including the following on each payment receipt:
- Tender Type: PayPal
- Currency
- PayPal’s Transaction ID (
ProviderTransactionID
field from the PXP responses), example how such a Paypal Transaction ID would look like: "7JD25560JU073942S" - Timestamp
- Store name and address
Automatic Cancellation of PayPal In-Store Deposit in case of communication error
If a PayPal In-Store Deposit Payment is not successful and results in one of those states (when PXP initiates the Deposit with PayPal), then the PXP system will automatically cancel refund to revert the request.
This applies to the following states of a PayPal In-Store Deposit payment:
InitiateRequestProviderCommunicationErrorOccurred
QueryPaymentStateCommunicationErrorOccured
QueryPaymentStateErrorReportedByProvider
The transaction will be in Cancelled
state in case the refund cancellation was successful.
In case the Cancellation failed, the payment will be in one of those states:
CancelCommunicationErrorOccurred
FailedToCancel
In this case, the PXP System will re-try the cancellation automatically.
Merchants can receive state change notification for the Cancellation outcome via the standard notification mechanism, see PaymentStateChangedNotification.
Cancel a PayPal In-Store Payment manually
Automatic Cancellation
The manual cancel option needs not be integrated by the merchant, because PXP system automatically cancels payments, see previous chapter.
Merchant can manually cancel a PayPal In-Store payment if it is in one of the following states, by using the executePaymentAction with actionID
= 1
(Cancel):
InitiateRequestProviderCommunicationErrorOccurred
QueryPaymentStateCommunicationErrorOccured
QueryPaymentStateErrorReportedByProvider
CancelCommunicationErrorOccurred
FailedToCancel
The transaction will be in Cancelled
state in case the refund cancellation was successful.
In case the Cancellation failed, the payment will be in one of those states:
CancelCommunicationErrorOccurred
FailedToCancel
Refund a PayPal In-Store Payment
When a customer returns some of his purchased items or goods in the store and has paid for it successfully with PayPal In-Store payment method before, the merchant can initiate the regarding refund In-Store with PayPal as well.
To initiate a refund for a PayPal In-Store payment, an initiatePaymentFromReference request using paymentMethodID = 400 ("PayPal Refund") has to be sent with the PaymentID of the original related PayPal In-Store payment (which must have been successfully completed DepositedByProvider
).
The paymentID
of the original PayPal In-Store payment must be used as originalPaymentID
in the initiatePaymentFromReferenceRequest
for creating the refund.
The merchant can decide to refund the full or a partial amount - but it must sum up to a maximum of the total captured amount of the PayPal payment.
Default Refund Window 180 days
A Paypal In-Store Capture payment can be refunded for 180 days. To change/extend this time window the merchant's PayPal Account Manager needs to be contacted.
Example initiatePaymentFromReferenceRequest
:
<?xml version="1.0" encoding="utf-8"?>
<initiatePaymentFromReferenceRequest
xmlns="http://www.cqrpayments.com/PaymentProcessing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<merchantID>B2BTestMerchant</merchantID>
<shopID>ProviderTesting</shopID>
<originalPaymentID>63948678-f523-4e32-8853-7590897124f3</originalPaymentID>
<merchantTransactionID>providertest_refundkiet7</merchantTransactionID>
<paymentMethodID>400</paymentMethodID>
<amount currencyCode="USD">2.5</amount>
<specificPaymentData>
<data xsi:type="keyStringValuePair">
<key>PaymentDescription</key>
<value>Your reason for refund</value>
</data>
</specificPaymentData>
<creationTypeID>12</creationTypeID>
</initiatePaymentFromReferenceRequest>
The PayPal payment for which the initiatePaymentFromReference request was sent will remain in state ExecutedByProvider
(142). A new payment which is linked to the original PayPal payment will be created.
ID | Name | Successful State |
---|---|---|
400 | PayPal Refund | Refunded (125) |
Example initiatePaymentFromReferenceResponse
:
<initiatePaymentFromReferenceResponse xmlns="http://www.cqrpayments.com/PaymentProcessing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<payment xsi:type="paymentWithPaymentAccount">
<merchantID>B2BTestMerchant</merchantID>
<shopID>ProviderTesting</shopID>
<paymentMethod>
<key>400</key>
<value>PayPal Refund</value>
</paymentMethod>
<merchantTransactionID>providertest_refundkiet7</merchantTransactionID>
<paymentID>e532840a-55c8-4663-99be-16b9b2966396</paymentID>
<userID>b4195619-0537-45bd-90ea-96cd3d9e8452</userID>
<paymentProvider>
<key>56</key>
<value>PayPal</value>
</paymentProvider>
<amount currencyCode="USD">2.5</amount>
<creationType>
<key>12</key>
<value>POS</value>
</creationType>
<userIP>127.0.0.1</userIP>
<state>
<id>0b027443-e8aa-4c98-a4d9-1bb97af36141</id>
<definition>
<key>125</key>
<value>Refunded</value>
</definition>
<createdOn>2021-12-21T08:15:34.3113386Z</createdOn>
<paymentStateDetails>
<detail xsi:type="keyStringValuePair">
<key>ProviderResponseCode</key>
<value>0</value>
</detail>
</paymentStateDetails>
</state>
<isExecuted>true</isExecuted>
<baseAmount currencyCode="EUR">1.88</baseAmount>
<paymentDetails>
<detail xsi:type="keyIntValuePair">
<key>OriginalPaymentID</key>
<value>39401058</value>
</detail>
<detail xsi:type="keyStringValuePair">
<key>ProviderTransactionID</key>
<value>063238933H511101R</value>
</detail>
<detail xsi:type="keyStringValuePair">
<key>ProviderExternalID</key>
<value>39418166</value>
</detail>
</paymentDetails>
<paymentAccount>
<paymentAccountID>6ce25a90-d525-4f8e-80c3-996920511bc2</paymentAccountID>
</paymentAccount>
</payment>
</initiatePaymentFromReferenceResponse>
Payment State Flow for all PayPal Partial Refund payments:
Automatic cancellation of refund in case of a request communication error
In case the refund request from PXP to PayPal results in an error state (RefundCommunicationErrorOccurred
or InitiateRefundErrorReportedByProvider
), PXP will try to cancel the refund request automatically to revert the transaction.
The refund transaction will be in Cancelled
state in case the refund cancellation was successful.
Error states would be:
CancelCommunicationErrorOccurred
FailedToCancel
In this case, the PXP System will re-try the cancellation automatically.
Merchants can receive state change notification for the Cancellation outcome via the standard notification mechanism, see PaymentStateChangedNotification.
POS Best Practices provided by PayPal
-
The POS should clearly label a tender type button as “PayPal" in an obvious manner so that
the process is intuitive to kick off the transaction process with little to no cashier training. When a
customer indicates he or she wants to Pay with PayPal, the next steps should be
obvious to the cashier. -
The POS should display the transaction status clearly to the cashier. E.g., “Waiting for Customer
Confirmation”, “Processing”, “Customer Cancelled,” etc. -
In the unlikely event that PXP returns unexpected content in an API response, the POS should recover gracefully.
Updated over 2 years ago