A2Billing authentication of forwarded calls

So let me guess. You’re using A2Billing on FreePBX – I don’t know how TrixBox or AsteriskNOW work, but the concept is the same – and whenever you forward a phone to an outside number it doesn’t work. Callers get prompted with “Please enter the complete PIN number” instead of having the call completed.

What’s happening – or what was happening in my case – is that the extensions entered in FreePBX have an associated accountcode field for A2Billing. When call forwarding is enabled and Asterisk initiates its own outbound calls, there is no account code passed on to the billing system. A2Billing doesn’t see the account code and prompts for a PIN. (The same goes if you’re using caller ID to authenticate instead of account codes: the outbound caller ID gets set to that of the incoming caller. That CID is not one recognized by A2Billing.)

The solution for me was to set a “default” account code on the PBX that would be applied to all outgoing calls if there weren’t one already attached to the call. This worked for me because there is only one account code for the entire PBX; if you’re using multiple A2Billing customers on a single PBX this won’t work unless you’re willing to forgo accurate accounting for the sake of users being able to forward calls.

The default context for outbound calls is from-internal which can’t be edited directly, as FreePBX overwrites it regularly. However, it includes another context called from-internal-custom which can be edited. It’s located in the file extensions_custom.conf and by default is only used for a couple of test extensions (1234 and 5678.) Here’s what I did with it:


[from-internal-custom]
exten => _X.,1,NoOp("Started with accountcode ${CDR(accountcode)}")
exten => _X.,n,GoToIf($[${LEN(${CDR(accountcode)})} > 0]?hasacct)
exten => _X.,n,Set(CDR(accountcode)=1234567890)
exten => _X.,n(hasacct),NoOp("Now has accountcode ${CDR(accountcode)}")

This can’t be put in from-internal-custom though. The priority sequencing (1, n, n, …) doesn’t reset between includes, so with the previous code you’d be at 5 before you got to the rest of the context, missing steps 1-4. As well, all outbound calls would be caught by that context, including ones that weren’t even going to A2Billing. So, assuming you followed the standard installation instructions for A2Billing, you should have a custom-freepbx-a2billing context that does the call to the A2Billing AGI script. This is the place to make the change.

[custom-freepbx-a2billing]
exten => _1NXXNXXXXXX,1,GotoIf($[${LEN(${CDR(accountcode)})} > 0]?end)
exten => _1NXXNXXXXXX,n,Set(CDR(accountcode)=1234567890)
exten => _011XXX.,1,GotoIf($[${LEN(${CDR(accountcode)})} > 0]?end)
exten => _011XXX.,n,Set(CDR(accountcode)=1234567890)
exten => _X.,n(end),Noop("Call proceding with accountcode ${CDR(accountcode)}")
exten => _X.,n,DeadAGI(a2billing.php|${OUT_${DIAL_TRUNK}:8})
exten => _X.,n,Hangup()

Basically it just checks for an existing account code; if it has one it does nothing, otherwise it will set it to my chosen code. I deal exclusively with account codes for authentication, but the same principle should apply to caller ID. However that would need to rely on an AGI script doing database checks to check for a known CID and set it to a chosen value if it wasn’t. A real fix for this would involve patching Asterisk to pull the account code for the originally dialed extension and attach it to the outbound call; that would be far beyond my abilities though!

A note about how call forwarding works: whether the forwarding is done on the endpoint or on the PBX using * codes, the forwarding is always performed by way of a new call being created by Asterisk. Phone based forwarding simply means that when the INVITE is sent to the endpoint, it replies with “302 Temporarily Moved” instead of “200 OK.” It does not mean that the phone initiates the call.

3 Replies to “A2Billing authentication of forwarded calls”

  1. Thanks!

    But I have two problems:
    – The script doesnt read my extension account code, so it uses the set account code (12345..)

    – Is there any way to make a call to a number, ex only calling to 444, and automatically says the credit .. on other numbers i dont want the system tell me the credit.

    thanks again

    1. Your first problem is the whole point of this workaround. You can’t get the account code from the extension, so you have to use the set account code. Your second problem, I have no idea. I’d suggest the A2Billing forums.

  2. Hi i tried you code on following build but no success,

    PIAF Version 2.0.6.4
    FreePBX Version 2.10.0.2
    Asterisk Version 1.8.23.1
    A2Billing Version 2.0.6

    my current custom-freepbx-a2billing context is
    [custom-freepbx-a2billing]
    exten => _X.,1,DeadAGI(a2billing.php|${OUT_${DIAL_TRUNK}:8})
    exten => _X.,n,Hangup()

    changed it to
    [custom-freepbx-a2billing]
    exten => _1NXXNXXXXXX,1,GotoIf($[${LEN(${CDR(accountcode)})} > 0]?end)
    exten => _1NXXNXXXXXX,n,Set(CDR(accountcode)=7275674201)
    exten => _011XXX.,1,GotoIf($[${LEN(${CDR(accountcode)})} > 0]?end)
    exten => _011XXX.,n,Set(CDR(accountcode)=7275674201)
    exten => _X.,n(end),Noop(“Call proceding with accountcode ${CDR(accountcode)}”)
    exten => _X.,n,DeadAGI(a2billing.php|${OUT_${DIAL_TRUNK}:8})
    exten => _X.,n,Hangup()

    but still it asking me to enter pin number,

    now if i change my from internal custom context then it works for external did to extension and extension is forwarded to other external number but not from internal extensions.
    [from-internal-custom]
    exten => _X.,1,NoOp(“Started with accountcode ${CDR(accountcode)}”)
    exten => _X.,n,GoToIf($[${LEN(${CDR(accountcode)})} > 0]?hasacct)
    exten => _X.,n,Set(CDR(accountcode)=7275674201)
    exten => _X.,n(hasacct),NoOp(“Now has accountcode ${CDR(accountcode)}”)

    any further fix for this issue?
    Thanks

Comments are closed.