genkgo / camt Goto Github PK
View Code? Open in Web Editor NEWPHP Parser for CAMT messages
License: MIT License
PHP Parser for CAMT messages
License: MIT License
Is there a way to know the type of the file actually parsed?
I mean camt.054.001.04
, camt.054.001.02
, camt.053.001.04
, ...
i'm not sure if this issue belongs to here:
when i install your awesome "camt" with composer, the files downloaded aren't the most recent from github. i never worked with composer, so apologize if this is a luser question/report.
Ist there PHP 8.0 support in the works? Can I help you testing?
Best regards,
Philip
Hi @frederikbosch,
I unfortunately don't have time anymore to work on this project. Could it be possible to remove my rights on it?
Thanks for your work! :)
Hi,
Do you have any plans to upgrade the Money dependency? to for example 3.0 or 1.3?
\Genkgo\Camt\DTO\ChargesRecord::setChargesIncludedIndicator
method name and related fields/methods contain non-ascii character that should be removed entirely.
Hi mainteners,
First of all, thank you for your excellent work.
This project seems compatible with the camt.054.001.04 version due to classes, tests (and so on, ...) presents in the repo, but the "readme" page says the opposite : only the camt.054.001.02 version is compatible.
Is there any limitation to take into account about the camt.054.001.04?
Best regards,
Sébastien
Hi All,
I wanted to know why into the camt.054.001.04 file amount appears under this format, with 2 decimals :
<Amt Ccy="CHF">5.40</Amt> <CdtDbtInd>DBIT</CdtDbtInd>
but the object return
[amount:Money\Money:private] => -540
Is there any reason ?
The below file is parsed as an Empty Document, not sure why, it's an official example file. Is the file broken or has the class something to do with it?
I would post the XML in here but I can't find a way to make a scrollable code field, here's the direct link to the ZIP file from the Bank's site: https://www.abnamro.nl/nl/images/Content/OneShop/000_Generiek/Zip/ZipOS_-_SEPA_-_CAMT053_voorbeeldbestand.zip
Why RelatedParty
class throws an exception if we try to retrieve an undefined account? I would like to display the IBAN if it is provided, but if it is not, an exception occurred.
So, how can I know if the account is available?
Lines 40 to 49 in 478aa0a
I'm trying to get PmtInfId
and NbOfTxs
within the Btch
of the entry details. See example piece of the XML below.
<NtryDtls>
<Btch>
<PmtInfId>PI REFERENCE-EXAMPLE</PmtInfId>
<NbOfTxs>8</NbOfTxs>
</Btch>
</NtryDtls>
I'm using the (simplified) code below to retrieve the relevant info such as amount, date, iban and transaction details.
$statements = $message->getRecords();
foreach ($statements as $statement) {
$entries = $statement->getEntries();
foreach ($entries as $entry) {
$details = $entry->getTransactionDetails();
foreach ($details as $detail) {
// ....
}
}
}
Is there any way to retrieve PmtInfId
and NbOfTxs
within the Btch
? Thanks
Hi, Thanks for this library it is very useful!
I experience an issue with the MoneyFactory, in conjunction with phpmoney\money.
camt/src/Util/MoneyFactory.php
Line 30 in 0ea252a
It converts 'DBIT' indicators to negative amounts, but somehow theres a subsequent issue with
Money\Parser\DecimalMoneyParser:
Cannot parse "-1,2" to Money. [C:\xampp\htdocs\domain3.local\vendor\moneyphp\money\src\Parser\DecimalMoneyParser.php:68]
[C:/xampp/htdocs/domain3.local/vendor/genkgo/camt/src/Util/MoneyFactory.php:35] Money\Parser\DecimalMoneyParser->parse('-1,2',MoneyCurrency::__set_state([]))
There is infact a 'DBIT' entry in my camt with amount 1.20 (CHF)
But I can't find out what's the problem here.
Thanks!
The dependency jschaedl/iban is marked as deprecated. Replace it with jschaedl/iban-validation. The library jschaedl/iban-validation does require PHP >= 7.1.3, but as far as i can see, there should not be a problem with this.
In case of some optional dates are missing in the XML file, the date returned by the library is the current one instead of NULL
.
For example, in the XML validation schema point of view, bookingDate and valueDate are optionals. But Theses dates are mandatory in case of CAMT.054 file. If one of these dates are not present, the returned date is the current one, which is obviously false.
I would suggest to test if the date is empty in the date decoder and return NULL if it is the case instead of the current date :
/**
* @param $date
* @return \DateTimeImmutable|null
*/
public function decode($date)
{
if(empty($date)) {
return null;
}
if ($this->format === null) {
$result = new \DateTimeImmutable($date);
} else {
$result = \DateTimeImmutable::createFromFormat($this->format, $date);
}
if ($result === false) {
throw new \InvalidArgumentException("Cannot decode date {$date}");
}
return $result;
}
But in that case, the signature of Entry
constructor must be modified to remove the DateTimeImmutable expected class for $bookingDate and $valueDate parameters because they can be also NULL
.
What do you think about this suggestion?
I would like to drop support of PHP 7.0 in our next major version (1.0.0) because it reached end of life 3 months ago, prevent us to integrate phpstan properly in our workflow and prevent us from type hinting nullable types and just add overhead to the general maintenance.
The idea being that for users who are still on PHP 7.0, they can use the freshly released camt 0.6.0.
@frederikbosch, @sdespont, @jarnovanleeuwen any thoughts on that ?
The xml tag for the RelatedAgents BIC is named in camt.053(.001.04) "BICFI".
I noticed, that camt.052 uses a "BIC" xml tag and is being tested with unit tests. For camt.053 an empty string is getting returned, as there is no "BIC" and no unit test. Is there a quick way to retrieve the BICFI for camt.053?
Thanks in advance for your response.
Hello,
I'm just raising a question about handling the CdtDbtInd and Amt values. Now the library does the work for you by checking CdtDbtInd and in case of DBIT the Amt is multiplied by -1. I see this may cut some corners when saving the values for further use (e.g. to database) so you don't have to consider the transfer direction. My question is should this be handled instead so that provide the user a method to get the CdtDbtInd and Amt values as they are and remove the "logic" from the library and implement it just towards the standard (and act as a pure parser)?
p.s. fantastic job from all the contributors, this library has saved a lot of time for me. I'm trying my best to participate.
Hello,
Is this camt supported ? Because I have some bugs with it with one of XML i have ?
Thank you
I have a camt file with the JPY currency. I've seen the other issue regarding of the deciaml issue.
My problem is, JPY has no decimal places.
The following balance entry:
<Bal>
<Tp>
<CdOrPrtry>
<Cd>CLBD</Cd>
</CdOrPrtry>
</Tp>
<Amt Ccy="JPY">27</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Dt>
<Dt>2020-02-20</Dt>
</Dt>
</Bal>
is parsed to
^ Money\Money^ {#135
-amount: "2700"
-currency: Money\Currency^ {#209
-code: "JPY"
}
}
And if I want to format this with money's DecimalFormatter (what in any other case works), then I get as formatted value JPY 2700
, what is wrong.
The only thing I can do now is to divide it with 100, if it's JPY.
The readme gives the following example:
$statements = $message->getRecords();
When executing the I got the following error: Call to undefined method Genkgo\Camt\Camt053\Message::getRecords()
.
I'm guessing this is a typo and it needs to be $message->getStatements();
. Is that the correct method?
Also, is it possible to get the parsed output as an array or json?
Hi,
Is there a reason why AmtDtls aren't available within a transaction detail???
I'm still investigating, but for me it looks like if <Ustrd>
is present then the information is not handled properly. I have couple of cases having both unstructured information (i.e. free text of max 140 chars) and Reference number (Strd->CdtrRefInf->Ref). In this case only Ustrd is available, if I remove the tag then the reference is available as it should.
I wonder why
/Decoder/Record.php
Line 76:
$amount = StringToUnits::convert((string) $xmlEntry->Amt);
converts all amounts into int thus truncates the decimal value
Hi
I followed your instructions to read the data of a single transaction.
$message = $reader->readFile( ...);
statements = $message->getRecords();
foreach ($statements as $statement) {
foreach($entries as $entry) {
$transactions=$entry->gettransactionDetails();
foreach($transactions as $transaction) {
$transaction <--
But inside the $transaction, there is this private array ([references:Genkgo\Camt\DTO\EntryTransactionDetail:private] => Array) containing reference-object(s).
[references:Genkgo\Camt\DTO\EntryTransactionDetail:private] => Array
(
[0] => Genkgo\Camt\DTO\Reference Object
(
[messageId:Genkgo\Camt\DTO\Reference:private] =>
When i don't missunderstand the ISO20022 guidelines, the "+Account Servicer Reference (AcctSvcrRef)" is within "References (Refs)" and this record has only a 0..1 relationship.
Shouldn't there be zero or one "Reference"- Object possible? If yes, the array seems confusing, because it looks like there are several "Reference"- Objects possible. Due i'm still learning, i hope this is no missunderstanding.
Best regards
Beat
I found the hard way that 0.3.0 is the last version compatible with php 5.6. there is no mention of that in readme.
After including Amt support myself i found this pull #44
and that its fixed in 0.4.0,
This is maybe the reason behind #46
It would be great if somebody updated the readme or released 0.3.1 with those fixes.
Hi,
this problem was already mentioned in issue #34, but there was no solution then.
A file from Triodos can be identified by the message id in the group header: it starts with 'TRIODOS/'.
Unfortunately, it seems some banks can send Camt files not respecting entirely the XSD.
Found in this PDF:
For the Swiss ISO 20022 Payments Standard, no special XML schemas will be issued for the "camt.052", "camt.053" and "camt.054" messages, in contrast to the messages for Credit Transfers (pain.001), Direct Debits (pain.008) and Status Reports (pain.002). The messages from Swiss financial institutions therefore correspond to the ISO standard, but do not use it in its entirety.
If I understand correctly, some Camt messages can be validate for banks but not following XSD… Therefore, shouldn't we be able to add an option to deactivate validator while reading and parsing the file?
At this point, the package only reads out for CAMT53 the CLBD and the OPBD values, but I would also need the available closing (CLAV) and available opening (OPAV) balance.
If I would create a PR to add these 2 additional types to the balances type, would that be merged or should I use my own fork?
It looks like there's a confusion between CdtDbtInd
(which is "CRDT" or "DBIT") and ChrgInclInd
(with could only be "true" or "false") here:
camt/src/Decoder/EntryTransactionDetail.php
Line 324 in a89fc7f
Also, is it possible to somehow retrieve "CdtDbtInd" individually from this DTO?
Hi there,
Is there any way yo get owner and financial institution details of an account? [053.v4]
camt/test/Unit/Camt053/Stubs/camt053.v4.xml
Lines 44 to 61 in 0ea252a
Thanks
I will develop a camt.053-File-Writer and thinking of using this project as a base. Would you be interested to merge in write support?
Is it possible to include a working example-file, or otherwise extend the getting-started in the readme? I cannot get it to read anything, I keep getting Fatal errors that Config and Reader are not found.
Hi
The postal address (PstlAdr) of the Debtor Agent Finance Institute records (RltdAgts/DbtrAgt/FinInstnId) seems not to be loaded from within the DebtorAgent
Is this function missing or do i have to load them manually?
Best regard
Beat
Are functions entry->getAccountServicerReference() and reference->getAccountServiceReference() named differently in purpose?
Hi there,
I'm getting the following error for these datetime
<FrDtTm>2021-11-30T00:00:00.000000000+01:00</FrDtTm>
<ToDtTm>2021-11-30T23:59:59.999999999+01:00</ToDtTm>
DateTimeImmutable::__construct(): Failed to parse time string (2021-11-30T00:00:00.000000000+01:00) at position 0 (2): The timezone could not be found in the database
#0 vendor/genkgo/camt/src/Decoder/Date.php(20): DateTimeImmutable->__construct()
#1 vendor/genkgo/camt/src/Decoder/Message.php(72): Genkgo\Camt\Decoder\Date->decode()
#2 vendor/genkgo/camt/src/Camt053/Decoder/Message.php(38): Genkgo\Camt\Decoder\Message->addCommonRecordInformation()
#3 vendor/genkgo/camt/src/Decoder.php(71): Genkgo\Camt\Camt053\Decoder\Message->addRecords()
#4 vendor/genkgo/camt/src/Reader.php(37): Genkgo\Camt\Decoder->decode()
#5 vendor/genkgo/camt/src/Reader.php(45): Genkgo\Camt\Reader->readDom()
#6 InteralPhpFile.php(35): Genkgo\Camt\Reader->readString()
i would like to parse my Stuzza files, this are basically simple camt.053.001.02 files, the header looks like this:
<?xml version="1.0" encoding="UTF-8"?><Document xmlns="ISO:camt.053.001.02:APC:STUZZA:payments:003" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
when running the script, it returns:
PHP Fatal error: Uncaught exception 'Genkgo\Camt\Exception\ReaderException' with message 'Unsupported format, cannot find message format with xmlns ISO:camt.053.001.02:APC:STUZZA:payments:003' in /opt/company/finance/banking/scripts/vendor/genkgo/camt/src/Reader.php:94 Stack trace: #0 /opt/company/finance/banking/scripts/vendor/genkgo/camt/src/Reader.php(38): Genkgo\Camt\Reader->getMessageFormatForXmlNs('ISO:camt.053.00...') #1 /opt/company/finance/banking/scripts/vendor/genkgo/camt/src/Reader.php(53): Genkgo\Camt\Reader->readDom(Object(DOMDocument)) #2 /opt/company/finance/banking/scripts/vendor/genkgo/camt/src/Reader.php(77): Genkgo\Camt\Reader->readString('<?xml version="...') #3 /opt/company/finance/banking/scripts/test.php(8): Genkgo\Camt\Reader->readFile('/mnt/company/fi...') #4 {main} thrown in /opt/company/finance/banking/scripts/vendor/genkgo/camt/src/Reader.php on line 94
the related sxd: http://www.stuzza.at/schemata/ISO.camt.053.001.02.austrian.003.xsd
Continuing on the ABN Amro example file, they put an incorrect IBAN in their example file:
<b>Fatal error</b>: Uncaught InvalidArgumentException: Unknown IBAN NL46ABNA0499998748
Is there a way to continue the import when this happens for one transaction or is this an edge case that never happens IRL and should I give up on the ABN Amro example file mentioned in my previous (closed) issue?
Hey @frederikbosch
What did you have in mind for supporting different versions of the Camt053 format?
A new Camt05300103 folder next to the existing Camt053 folder which would serve as a base for all Camt053 versions?
PS, where did you get the XSD file for the camt.053.001.02 format? I can't seem to find it for the camt.053.001.03 format.
Thanks
Regarding #37, @antlih is right : data can be loss in some cases.
Credit Suisse uses remittance information structure like this :
<RmtInf>
<Ustrd>?REJECT?0</Ustrd>
<Strd>
<CdtrRefInf>
<Tp>
<CdOrPrtry>
<Prtry>ISR Reference</Prtry>
</CdOrPrtry>
</Tp>
<Ref>333333333333333333333333334</Ref>
</CdtrRefInf>
</Strd>
</RmtInf>
With this kind of data, $transactionDetail->getRemittanceInformation()->getMessage();
will returns ?REJECT?0
instead of 333333333333333333333333334
.
I would suggest to use new classes in order to retrieve full and both structured and unstructured data. It would also permit to retrieve the AddtlRmtInfoption which contains information about a potential reject code from the bank.
I can develop this feature, but, it will break the compatibility because of getMessage() would be dropped. The data would be retrieved like this :
ISR reference number
$transactionDetail->getRemittanceInformation()->getStructured()->getCreditorRefereneInformation()->getReference();
Additional remittance information (reject code)
$transactionDetail->getRemittanceInformation()->getStructured()->getAdditionalRemittanceInformation();
Unstructured data
$transactionDetail->getRemittanceInformation()->getUnStructured();
Guys, any idea? How do you handle Credit Suisse CAMT.054 files?
Hi, first of all, great lib!
Today i made an export from the Tridos Bank and it gave me this date:
2017-08-09T23:59:59.999999999
Maybe in the $this->dateDecoder->decode we can check the format of the date before trying to parse it?
I am not familiar with all the formats of CAMT, but can we assume that the format needs to be YYYY-MM-DDTHH:II:SS ???
PHP can handle 6 digits for the milliseconds, but 9 are too much...
Let me know if you have any idea / suggestions...
Kind regards,
Sander
Hi,
I have camt053 files from triodos bank that has an extra .999999 behind the dates in the files. If I'm correct this is some oracle format. The datetimeimmutable fails on this. Any ideas how to solve other then editing the file before parsing it?
Thnx
First of all. Thank you for this great library.. It saved me a lot of hours.
The only "problem" I had was the handling of the BadMethodCallException
's. I do automatically end up catching way too much BadMethodCallException
to only set a default value (mostly null
by myself) in the catch block.
I know that changing this behaviour will cause a BC break. But are there any other reasons for that approach?
It seems IBAN is not the only way of identification of an account, in camt 053.
It can be replaced by another identification of type GenericAccountIdentification1, containing:
I'm not sure how to handle this.
@frederikbosch Currently there is no way to determine which XML attribute you use when getting all available opening and closing balances. In our system this is required because one XML attribute might be more reliable then the other. Is there any change this could be implemented in future development? I could open a pull request if you like to.
The only thing that needs to be added is a field an the DTO\Balance object named Code. Which contains the $code = (string) $xmlBalance->Tp->CdOrPrtry->Cd;
e.g. OPBD
How to get Debtor (company/private) identification number?
I looked the code and I didn't find methods and attributes for that - it would be very useful feature to identify company or private person transaction with identification number not only names or bank accounts.
Maybe Debtor or even Creditor class can be complemented with additional methods to get private and organisation ID.
Would it be possible to implement all DTO's with JsonSerializable?
I'm not an expert but I had an error on trying to get RelatedPartyDetails. It seems to be a wrong function denomination in RelatedParty.php:
public function getRelatedPartyType(): RelatedPartyTypeInterface
would not better be?
public function getRelatedPartyDetails(): RelatedPartyTypeInterface
thanks for your great job!
When reading a Camt053 xml (ABN-AMRO) I get error messages when I use getRemittanceInformation().
It seems that ABN-AMRO does not always include the RemittanceInformation in the XML.
I have disabled line 163 of genkgo/camt/src/DTO/EntryTransactionDetail.php and now I can read the XML.
Is ABN-AMRO to blame for this?
Parsing a camt.052.001.02 file seems to ignore the decimal point when parsing the amounts.
For example 65.50 accessed with Entry->getAmount()->getAmount() prints -6550
Minus is correct since it are returned bookings but where got the decimal point lost?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.