brucelin
brucelin

Reputation: 1021

3120 error from ReceivePaymentAddRq - php devkit

I'm adding receive payments using php devkit here https://github.com/consolibyte/quickbooks-php.

The problem is no response from the quickbooks and also there is no issue. I checked the web connector logs and php log files. But response function is not called ever.

I'm pretty sure this was working well until few days ago. I have no idea what the exact problem is.

qbxml version: 10.0

request xml:

<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="10.0"?>
<QBXML>
    <QBXMLMsgsRq onError="continueOnError">
        <ReceivePaymentAddRq requestID="153">
            <ReceivePaymentAdd>
                <CustomerRef >
                    <FullName >Duncan, Dave</FullName>
                </CustomerRef>
                <TxnDate >2023-12-15</TxnDate>
                <RefNumber>Wire</RefNumber>
                <TotalAmount>2585.00</TotalAmount>
                <PaymentMethodRef><FullName>Check</FullName></PaymentMethodRef>
                <Memo>Paid In Full</Memo>
                <AppliedToTxnAdd>
                    <TxnID>28CA9-1702576301</TxnID>
                    <PaymentAmount >2585.00</PaymentAmount>
                </AppliedToTxnAdd>
            </ReceivePaymentAdd>
        </ReceivePaymentAddRq>
    </QBXMLMsgsRq>
</QBXML>

php scripts:

$map = array(
QUICKBOOKS_ADD_RECEIVE_PAYMENT => array( '_quickbooks_payment_add_request', '_quickbooks_payment_add_response' ));

$errmap = array(
        // QUICKBOOKS_IMPORT_CUSTOMER => '_quickbooks_customer_query_error', 
        '*' => '_quickbooks_error_catchall',                // Catch any other errors that might occur
..

$hooks = array(
        QuickBooks_WebConnector_Handlers::HOOK_LOGINSUCCESS => '_quickbooks_sync_to_qb',    // call this whenever a successful login occurs
    );
function _quickbooks_sync_to_qb($requestID, $user, $hook, &$err, $hook_data, $callback_config)
{ 
    $database = new Database();
    $db = $database->getConnection();

    $Queue = new QuickBooks_WebConnector_Queue($database->dsn);
    $payment = new Payment($db);
    $payment->needSync = true; 

    $stmt = $payment->read();
    $num = $stmt->rowCount();

    if ($num > 0) {
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

            $Queue->enqueue(QUICKBOOKS_ADD_RECEIVE_PAYMENT, $row['id']);
        }
    }


    $database->destroy();
}
function _quickbooks_payment_add_request($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale)
{error_log('start from here');
    $database = new Database();
    $db = $database->getConnection();

    // Grab the data from our MySQL database
    $payment = new Payment($db);
    $payment->id = (int) $ID;
    error_log('1');
    // Validation
    $stmt = $payment->read();
    $num = $stmt->rowCount();

    if ($num > 0) {error_log('2');
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

            extract($row);

            // get trasaction id from invoice
            $invoice = new Invoice($db);
            $invoice->refNumber = $invoice_ref_number;
            error_log('21');
            $xml = '<?xml version="1.0" encoding="utf-8"?>
                <?qbxml version="10.0"?>
                <QBXML>
                    <QBXMLMsgsRq onError="continueOnError">
                        <ReceivePaymentAddRq>
                            <ReceivePaymentAdd>';

                    if ($customer_ref_listid != '' || $customer_ref_fullname != '') {

                        $xml .= '<CustomerRef >';

                        if ($customer_ref_listid != '') {

                            $xml .= '<ListID  >' . $customer_ref_listid . '</ListID>';

                            // invoice customer ref listid
                            $invoice->customerRefListID = $customer_ref_listid;
                        }
                        if ($customer_ref_fullname != '') {

                            $xml .= '<FullName >' . $customer_ref_fullname . '</FullName>';

                            // invoice customer ref fullname
                            $invoice->customerRefFullName = $customer_ref_fullname;
                        }

                        $xml .= '</CustomerRef>';
                    }


                    $stmt = $invoice->read();
                    $num = $stmt->rowCount();
                    $txnID = '';
                    $txnDate = '';

                    if ($num > 0) {

                        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

                            $txnID = $row['txn_id'];
                            $txnDate = date_format(date_create($row['txn_date']), 'Y-m-d');

                        }
                    }


                        $xml .= '<TxnDate >' . $txnDate . '</TxnDate>
                                <RefNumber>' . $ref_number . '</RefNumber>
                                <TotalAmount>' . $total_amount . '</TotalAmount>
                                <PaymentMethodRef>';

                        if (!empty($payment_method_ref_listid)) {

                            $xml .= '<ListID>' . $payment_method_ref_listid . '</FullName>';
                        }
                        if (!empty($payment_method_ref_fullname)) {

                            $xml .= '<FullName>' . $payment_method_ref_fullname . '</FullName>';
                        }

                        $xml .= '</PaymentMethodRef>
                                <Memo>' . $memo . '</Memo>
                                <AppliedToTxnAdd>
                                    <TxnID>' . $txnID . '</TxnID>
                                    <PaymentAmount >' . $total_amount . '</PaymentAmount>
                                </AppliedToTxnAdd>
                            </ReceivePaymentAdd>
                        </ReceivePaymentAddRq>
                    </QBXMLMsgsRq>
                </QBXML>';
                error_log('22');
        }
        error_log('3');
        $database->destroy();
        error_log('4');
        error_log($xml);
        return $xml;
    }
    error_log('5');
    $database->destroy();
    return false;

}

This function seems not called even it is registered properly.

function _quickbooks_payment_add_response($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
{error_log('_quickbooks_payment_add_response');
    $database = new Database();

EDIT: VERBOSE LOG

20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_sendRequestXML() : qbNationality="US"
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_sendRequestXML() : qbXMLMajorVers="13"
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_sendRequestXML() : qbXMLMinorVers="0"
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_sendRequestXML() : Received from sendRequestXML() following parameter:
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_sendRequestXML() : strRequestXML =
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_sendRequestXML() : XML dump follows: -

<?xml version="1.0" encoding="utf-8"?>
                <?qbxml version="10.0"?>
                <QBXML>
                    <QBXMLMsgsRq onError="continueOnError">
                        <ReceivePaymentAddRq requestID="158">
                            <ReceivePaymentAdd><CustomerRef ><FullName >Duncan, Dave</FullName></CustomerRef><RefNumber>Wire</RefNumber>
                                <TotalAmount>2585.00</TotalAmount>
                                <PaymentMethodRef><FullName>Check</FullName></PaymentMethodRef>
                                <Memo>Paid In Full</Memo>
                                <AppliedToTxnAdd>
                                    <TxnID>28CA9-1702576301</TxnID>
                                    <PaymentAmount >2585.00</PaymentAmount>
                                </AppliedToTxnAdd>
                            </ReceivePaymentAdd>
                        </ReceivePaymentAddRq>
                    </QBXMLMsgsRq>
                </QBXML>

20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_sendRequestXML() : Request xml received.
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.ProcessRequestXML() : Processing request #1
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.ProcessRequestXML() : REQUEST: received from application: size (bytes) = 666
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.ProcessRequestXML() : Sending request to QuickBooks.
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.ProcessRequestXML() : Response received from QuickBooks: size (bytes) = 245
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.ProcessRequestXML() : Sending response back to application.
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_receiveResponseXML() : *** Calling receiveResponseXML() with following parameters:
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_receiveResponseXML() : wcTicket="35382423-f97d-5fc4-3935-d4a7629367a8"
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_receiveResponseXML() : response =
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_receiveResponseXML() : XML dump follows: -

<?xml version="1.0" ?>
<QBXML>
<QBXMLMsgsRs>
<ReceivePaymentAddRs requestID="158" statusCode="3120" statusSeverity="Error" statusMessage="Object &quot;28CA9-1702576301&quot; specified in the request cannot be found. " />
</QBXMLMsgsRs>
</QBXML>


20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_receiveResponseXML() : hresult=""
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_receiveResponseXML() : message=""
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_receiveResponseXML() : Received from receiveResponseXML() following parameters:
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_receiveResponseXML() : more="100">
20190327.20:42:17 UTC   : QBWebConnector.SOAPWebService.do_receiveResponseXML() : Done. No more to process.

Upvotes: 0

Views: 155

Answers (1)

Keith Palmer Jr.
Keith Palmer Jr.

Reputation: 27952

It's hard to tell without seeing the logs (Web Connector logs in VERBOSE mode and also the quickbooks_log SQL table output) exactly what's wrong here, but here's at least a few things to check:

1. Are you SURE you're not getting a response from QuickBooks?

You indicate "The problem is no response from the quickbooks" but that may not be the actual case here.

Have you verified that you're not getting a response in the actual logs? For example, if an error were to occur (e.g. maybe the customer or the invoice does not exist) then QuickBooks will send back an error but your response function won't get called -- an error handler will get called instead.

Do you have something like this in your code?

$errmap = array(
    3070 => '_quickbooks_error_stringtoolong',              // Whenever a string is too long to fit in a field, call this function: _quickbooks_error_stringtolong()
    // ... more error handlers here ...
    );

(from https://github.com/consolibyte/quickbooks-php/blob/master/docs/web_connector/example_web_connector.php )

Maybe an error handler is getting called instead of your response function?

2. You aren't passing a requestID="..." attribute

The Web Connector uses a requestID="..." attribute in the XML to be able to match up the outgoing requests with the incoming responses. You're not using it, but should be.

Change this:

<ReceivePaymentAddRq>

To this:

<ReceivePaymentAddRq requestID="' . $requestID . '">

Read more:

3. You're not XML encoding values

For this:

<Memo>' . $memo . '</Memo>

If $memo is set to bla bla <something> bla bla then you're going to end up with malformed XML:

<Memo>bla bla <something bla bla</Memo>

You should be XML-encoding these values.

4. The $memo variable is undefined

You're saying that your resulting XML looks like this:

<Memo>Paid In Full</Memo>

But when I look at your code, $memo is undefined. This makes me suspect that the XML you pasted here is not the actual XML you're sending to QuickBooks.

Where does that variable get set to Paid In Full? It doesn't get set anywhere in the code you pasted.

This should also be causing a PHP error/warning about an undefined variable, which could be breaking things.

5. Make sure your Web Connector is in VERBOSE mode

VERBOSE mode in the Web Connector shows a lot more data. You should be able to easily find the request in question and analyze/post the relevant logs.

6. Check the quickbooks_log and quickbooks_queue tables

What do they show/say?

What is the status (qb_status field) and message on the queued up record (quickbooks_queue SQL table)?

Upvotes: 1

Related Questions