Manila MRT3 EMV and QR Acceptance - The GCash Commuter QR Code
As reported earlier, on July 25, 2025, MRT-3 in Manila started to accept GCash QR codes directly at the gate, without the need to buy a prepaid ticket.
I have not found reports of first-hand experience with this new feature. All I can talk about here is what I can deduce from the user experience with the GCash application and from comparing the QR code data to the QCAT specification. I cannot say anything about processing until I have tried it myself.
In summary, there does not seem to be much support for interoperability. I would say that the e-wallets may have missed a chance to compete with the payment cards schemes in the AFCS market.
The User Experience
GCash is using a QR code specifically constructed for the use at the automated gate or validator. The pictures show the four screens a user goes through to get such a QR code.
-
Tap the QR code icon on the Home Screen.
-
Tap the “Generate QR code” option to open the QR scanning screen.
-
Tap the “Commute” option on the generate QR code screen.
-
Show the QR code on the Commute screen to the scanner at the automated gate.
The option to save the QR code does not work, which is a wise decision. The "Other ways to commute" option leads to some additional interesting functionality, which I will look at in a future post.
The QR code data
The QR code payload follows[1] the EMV standard for customer presented QR codes (1) and borrows some details from the QCAT specification (2). In the QCAT GitHub repository, there is a lot more detailed information about the concepts I am mentioning in this article.
At the top level the data contains the EMV payload indicator (tag: 0x85
) and one Application Template.
The single Application Template (tag: 0x61
), contains two EMV-defined simple TLV data elements. The first one is the ADF Name (tag: 0x4F
), which is “GCASH”. The second data element is the Application PAN (tag: 0x5A
).
While the ADF name has no prescribed encoding format, the Application PAN is supposed to be a number that is encoded as compressed numeric in up to 16 bytes. The EMV crowd did not foresee that anybody might want to use account numbers that do not follow the credit card number standard. GCash chose the practical approach of ignoring the EMV specification and instead encode the account number as UTF-8 encoded string. In my case, it had 27 characters.
The GCash data lives in the Application Specific Transparent Template (tag: 0x63
). The data elements inside this template are using the tag numbers of the QCAT specification, but do not follow the QCAT specification very well.
In the QR code that was generated by the Gcash application on my phone, there are five data elements:
- The ticket ID (tag:
0xC1
) -
The QCAT specification section 8.2.1.1 defines the ticket ID as a long integer that is encoded binary with the minimum number of bytes and in big-endian order. GCash chose a UTF-8 encoding of the ticket number that contains alphanumeric digits. The ticket number starts with
GC-
followed by the date (for example08012025-
) and ends with an integer with 10 digits (that is about 10 billion ticket IDs per day).The QCAT standard envisioned a separation of ticket and QR code, which means that the ticket number remains the same when the QR code is refreshed. In the GCash case, it looks as if the ticket number changes with every refresh of the QR code.
I think it would have been slightly more straight forward to link entry and exit transactions using a common ticket number rather than the account number. Maybe the backend system keeps track of the link between ticket number and account number.
- The ticket creator ID (tag:
0xC2
) -
The value is two bytes:
0x00 0x01
. QCAT section 8.2.1.2 says that this would be an unsigned integer that needs to be encoded in the least amount of bytes, which in this case would just be0x01
.The idea of the ticket creator was that within the QCAT scheme there can be many ticket creators, which are defined as the organizations that will guarantee settlement of the ticket price [2]
In any case, unless GCash envisions the creation of tickets by other organizations, the creator ID is redundant as they define their own ADF Name. They could also have saved three bytes.
- The validity period (tag:
0xC4
) -
QCAT section 8.2.1.4 says that the validity period is defined as the number of seconds during which the ticket is valid after the creation or the effective time. GCash, on the other hand, defines it as a timestamp (seconds after unix epoch) after which the ticket becomes invalid. It is binary-encoded in four bytes.
As far as I can tell, the validity period is reset every time a new QR code is generated. I have not done enough tests to say with a hundred percent confidence, but doesn’t that mean the ticket will never expire as long as it keeps refreshing?.
- The refresh time (tag:
0xC8
) -
The refresh time was meant to provide an option for the ticket creator to refresh the QR code without changing any other ticket data, including the ticket expiry date.
In the GCash case, the refresh time is indeed indicating when a new QR ticket needs to be generated. The application refreshes the ticket every 20 seconds or so. This should be enough to prevent most copy-counterfeit attacks.
- Signature (tag:
0xDE
) -
There is nothing much I can say about the signature as GCASH will obviously not publish the encryption standard (also see (3) and (4))
The only observation I have is that the first byte is supposed to be the version number of the signature algorithm encoded as an unsigned integer in one byte. I do not think GCash is using this convention. It looks more like an ASN.1/BER encoded sequence of two 256-bit integers.
Interoperability
The QR code was probably not designed with interoperability in mind. Any validator accepting this QR code will have to be specifically programmed to understand the tags and value formats of the “GCASH” template. Other participants would need to design their own format and put it into a template with their own ADF Name.
Even more problematic is the deviation from the EMV specification while using the format and tag numbers defined in there. The validator would need to go into the application specific transparent template to analyze the EMV data elements, which is pretty much against everything that was envisioned when the EMV specification was designed (as bad as it is).
I could also not find anything in the data that would help the validator selecting cryptographic credentials to validate the signature, which would make supporting multiple ticket creators and the introduction of new cryptographic keys challenging.
Especially in the area of account based ticketing, interoperability is the key, as the transport operators and AFCS providers cannot be expected to build an entirely new processing module every time a new e-wallet comes along.
The power of a common standard has been demonstrated many times by QR payments standards championed by the Central Banks. The QRPh specification is a good example.
Standardization must not stop at the QR payload. Common settlement procedures, performance expectations, dispute management and security standards must be unified as well.
Without a common e-wallet ticketing standard, the EMV/NFC based cards will always win, as the interface to the gates and validators is well-defined, and there are only a few schemes to deal with for settlement, risk management and so forth.
However, as soon as anybody with an e-wallet application could “issue” a commuter QR code without the need for changes at the gate/validator, there would be no stopping the AFCS revolution in the same way standardized QR-codes and processing standards have revolutionized the payment landscape.
References
(1) EMVCo, “EMV Code Specification for Payment Systems (EMV QRCPS) - Consumer-Presented Mode,” EMVCo, LLC, Technical Standard 1.1, Nov. 2020.
(2) AF Payments, Ingo Noka, “QR Code Standard for Transport Ticketing - Standard.” GitHub, Sep. 2019, [Online]. Available: https://github.com/afpayments/QCAT_QR_TICKETING_STANDARD.
(3) AF Payments, Ingo Noka, “QR Code Standard for Transport Ticketing - Risk Management.” GitHub, Sep. 2019, [Online]. Available: https://github.com/afpayments/QCAT_QR_TICKETING_STANDARD.
(4) AF Payments, Ingo Noka, “Public Key Management System for Signature Algorithm Version 1 and 2.” GitHub, Sep. 2019, [Online]. Available: https://github.com/afpayments/QCAT_QR_TICKETING_STANDARD.