NAME

Business::cXML::Transmission - cXML transmission

SYNOPSIS

use Business::cXML::Transmission;
$msg = parse Business::cXML::Transmission $incoming_cxml_string;

DESCRIPTION

Parser and compiler for cXML transmissions.

See: http://xml.cxml.org/current/cXMLUsersGuide.pdf

The creation of these transmissions should normally be left to Business::cXML, which does some handy initialization for you. Of main concern for manual processing is our "payload()".

METHODS

new( [$input] )

Without $input, returns an empty Business::cXML::Transmission ready to be populated.

With $input, returns a Business::cXML::Transmission if parsing was possible, or an arrayref with two elements if there was an error. The first element is a status code, and the second contains a string with more details, if available. Input is expected to be a full XML document string, optionally encoded in Base64 (i.e. the contents of a cxml-base64 form variable).

Possible codes:

406

The input XML is invalid

400

The input XML is valid, but the cXML structure is incomprehensible

toForm( %arguments )

In a scalar context, returns an HTML string representation of the current cXML data structure, in cXML "URL-Form-Encoding" (a form with a hidden cxml-base64 value). Returns an empty string if we have an internal error.

To help identify problems, in a list context it returns an error string (or undef) and the HTML string (probably empty, depending on the type of error).

Possible %arguments keys:

url

Mandatory, should be from a PunchOutSetupRequest/BrowserFormPost.

target

Optional, the HTML frame target to specify in the FORM

submit_button

Optional, override submit button HTML with your own

toString()

In a scalar context, returns an XML string representation of the current cXML data structure.

In the event that our XML document were not valid, a hard-coded 500 status Response with explanation will be returned instead of the prepared transmission.

To help identify problems, in a list context it returns an error string (or undef) and the XML string.

freeze()

Store the results of "toString()" internally and return it (in a scalar context). This is what "toString()" will always return until "thaw()" is eventually called. Has no effect if the transmission is already frozen.

This helps comply with cXML's recommendation that multiple attempts to deliver a transmission have the same payloadID and timestamp values.

To help identify problems, in a list context it returns an error string (or undef) and the XML string. Note that multiple calls will only yield an error (if any) on the first call, and undef thereafter.

thaw()

Destroy the internally stored results of "toString()". Modifications to internal data will once again produce changes in what "toString()" returns.

reply_to( REQUEST )

Initialize "type", "inreplyto", "from", "to" and "sender" in reciprocity with request data.

from( [%properties] )
to( [%properties] )
sender( [%properties] )

Returns the associated Business::cXML::Credential object.

With %properties, it first calls Business::cXML::Credential::set(). In the case of from(), sets both from and sender objects, therefore if you need to override this behavior, be sure to set sender after from.

Note that you could also pass a single Business::cXML::Credential object, in which case it would replace the current one outright. In the case of from(), note that the object reference will be given to sender intact and a clone will be copied into from().

is_test( [$bool] )

Get/set whether this transmission is in test mode (vs production).

timestamp

Read-only, the transmission's creation date/time.

id

Read-only, the transmission's payload ID.

inreplyto( [$id] )

Get/set the payload ID of the transmission we're responding to.

is_message( [$bool] )
is_request( [$bool] )
is_response( [$bool] )

Get/set whether this transmission is a Message, Request or Response. The transmission's class is only modified when $bool is true.

Setting any of these loses any data currently in "payload", so be sure to do it early!

lang( [$code] )

Get/set the language for displayable strings included in this transmission. Can be changed, but cannot be unset. Default: en-US. For an incoming transmission, this should be a hint to the user's preferred display language.

type( [$name] )

Get/set the type of document. Can be changed, but cannot be unset. For example: Profile or PunchOutSetup.

Caution: Setting a type loses any data currently in "payload", so be sure to do it early!

payload

Read-only. If a native implementation for the current transmission type is available (i.e. Business::cXML::Request::PunchOutSetup), it is made available ready-to-use via this property. For incoming transmission, it is fully populated with parsed data.

If accessed after previously using "xml_payload", this would cause the native payload to be recreated from the XML payload as it currently stands, preserving any (valid) changes done on the XML side into the native version.

xml_payload

Read-only. The XML::LibXML::Element representing the "SomethingMessage", "SomethingRequest" or "SomethingResponse" section of the transmission.

Its node name is automatically determined in "toString()", but you are free to add/change other attributes and child elements. Returns undef for incoming (parsed) transmissions.

Accessing this property causes the destruction of "payload" if it existed. This is in place so that your own parsing of LibXML structures takes precedence over ours to hopefully make future updates seamless in the event of conflicts. Thus, while you can modify the native payload, then modify the XML version, switching back again to native would lose all data.

status( [ $code, [$description] ] )

Get/set transmission's cXML 3-digit status code. (None by default.)

$description is an optional explanatory text that may be included in the status of a response.

cXML defines the following status codes, which are the only ones accepted.

Success:

200 OK

Request executed and delivered, cXML itself has no error

201 Accepted

Not yet processed, we'll send a StatusUpdate later

204 No Content

Request won't get a Response from server (i.e. punch-out cart didn't change)

280 [Described like 201]
281 [Described like 201]

Permanent errors:

400 Bad Request

Parsed OK but unacceptable

401 Unauthorized

Request/Sender credentials not recognized

402 Payment Required

Need complete Payment element

403 Forbidden

Insufficient privileges

406 Not Acceptable

Request unacceptable, likely parsing failure

409 Conflict

Current state incompatible with Request

412 Precondition Failed

Unlike 403, the precondition was described in a previous response

417 Expectation Failed

Request implied a resource condition that was not met, such as an unknown one

450 Not Implemented

Server doesn't implement that Request (so client ignored server's profile?)

475 Signature Required

Document missing required digital signature

476 Signature Verification Failed

Failed signature or unsupported signature algorithm

477 Signature Unacceptable

Valid signature but otherwise rejected

Transient errors:

500 Internal Server Error

Server was unable to complete the Request (temporary)

550 Unable to reach cXML server

Applies to intermediate hubs (temporary)

551 Unable to forward request

Because of supplier misconfiguration (temporary)

560 Temporary server error

Maintenance, etc. (temporary)

AUTHOR

Stéphane Lavergne https://github.com/vphantom

ACKNOWLEDGEMENTS

Graph X Design Inc. https://www.gxd.ca/ sponsored this project.

COPYRIGHT & LICENSE

Copyright (c) 2017-2018 Stéphane Lavergne https://github.com/vphantom

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.