FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index mod_harbour Best Practices for modern Web/DBF integrations: Cloudflared, Mollie, MessageBird?
Posts: 6983
Joined: Fri Oct 07, 2005 07:07 PM
Best Practices for modern Web/DBF integrations: Cloudflared, Mollie, MessageBird?
Posted: Sat Mar 07, 2026 08:53 AM

Hello friends,

In our team, we are currently modernizing our Harbour/DBF backend to better integrate with the modern web (Omnichannel messaging & seamless payments) while strictly keeping our DBFs and business logic safe and on-premise (GDPR compliance).

To avoid reinventing the wheel and writing dozens of custom API integrations, we are thinking about adopting a "standardized stack" of European API providers. The goal is to build our Harbour code against these APIs once, and ideally share our experiences (and code snippets) with the community.

This is the architecture we are currently planning to implement:

  1. Security & Webhooks -> Cloudflared (Argo Tunnel) Instead of opening local ports on our routers to receive Webhooks from external APIs, our local Harbour server connects outbound to a Cloudflare Tunnel. This means our local DBFs are completely shielded from the public internet, but we can securely receive JSON Webhooks (e.g., from payment providers).

  2. Payment Gateway -> Mollie Instead of touching credit card data (and dealing with PCI-DSS compliance), we want to use the Mollie API. We create a payment link in Harbour -> send it to the guest -> Mollie handles the rest (Credit Card, Apple Pay, SEPA) -> Mollie sends a secure Webhook back through Cloudflared to our server, and Harbour updates the BELEGUNG.DBF to "PAID".

  3. Communication (WhatsApp/SMS) -> MessageBird We are looking to use MessageBird (a European alternative to Twilio) to send automated pre-arrival WhatsApp messages or SMS directly from our Harbour logic. Incoming replies from guests trigger a Webhook that Harbour saves directly into the guest's HISTORY memo field.

  4. Transactional E-Mails -> Brevo (formerly Sendinblue) Sending booking confirmations via REST API instead of dealing with complex SMTP setups in Harbour.

My questions to the community:

Is anyone here already using Cloudflared tunnels to easily receive incoming Webhook-JSONs straight into a Harbour-compiled microservice?
Has anyone already written integration classes for Mollie or MessageBird/Brevo in Harbour that they could share, or would you be interested in joining forces to build a stable class for these specific providers?
I believe that if some of us agree on a shared stack of standard providers like these, we can save a tremendous amount of time maintaining different API endpoints.

Looking forward to your thoughts and experiences!

Best regards, Otto

//-- HARBOURINO INBOUND_WEBHOOK Start --//

FUNCTION handle_inbound_msg( cJson, cRequestId )

LOCAL hReq        := {=>}
LOCAL nDecoded    := 0
LOCAL cResponse   := ""
LOCAL cSource     := ""
LOCAL cSender     := ""
LOCAL cMessage    := ""
LOCAL cReference  := ""
LOCAL cStatus     := ""
LOCAL hAuditRow   := {=>}

// --- Body prüfen ---
nDecoded := hb_jsonDecode( cJson, @hReq )
IF ValType( nDecoded ) != "N" .OR. nDecoded <= 0
    RETURN hb_jsonEncode({ "success" => .F., "error" => "Invalid Webhook JSON" })
ENDIF

// 1. Von wem kommt der Webhook? (MessageBird, Brevo oder Mollie)
cSource := Upper( hb_HGetDef( hReq, "provider", "UNKNOWN" ) )

// --- FALL A: EINE NACHRICHT (WhatsApp / SMS / Mail) ---
IF cSource == "MESSAGEBIRD" .OR. cSource == "BREVO"
    
    // Die Nummer oder E-Mail des Gastes
    cSender  := hb_HGetDef( hReq, "sender_address", "" ) 
    // Der Text, den der Gast geschrieben hat
    cMessage := hb_HGetDef( hReq, "message_text", "" )
    
    // OPTIONAL: Wenn wir direkt den Kunden finden wollen
    // nKundenRecNo := FindCustomerByContact( cSender )
    
    // Neue Nachricht in die POSTEINGANG.DBF (oder AUDIT) speichern
    USE ( "X:\xwhdaten\AUDIT\INBOX.DBF" ) NEW ALIAS INBOX SHARED
    INBOX->( DbAppend() ) // Neue Zeile anhängen
    
    REPLACE INBOX->DATETIME WITH DToC(Date()) + " " + Time()
    REPLACE INBOX->PROVIDER WITH cSource
    REPLACE INBOX->SENDER   WITH cSender
    REPLACE INBOX->MESSAGE  WITH Left(cMessage, 250) // Gekürzt auf DBF-Feldlänge
    REPLACE INBOX->READ     WITH .F. // Ungelesen für die Rezeption!
    
    INBOX->( DbCommit() )
    INBOX->( dbCloseArea() )
    
    // Antworte dem Provider sofort "OK", sonst schickt er das selbe Paket in 5 Min. nochmal!
    RETURN hb_jsonEncode({ "success" => .T., "message" => "Inbox logged" })


// --- FALL B: EINE ZAHLUNG (Mollie) ---
ELSEIF cSource == "MOLLIE"
    
    // Mollie übergibt uns meistens eine eigene Referenz (z.B. deine Buchungsnummer)
    cReference := hb_HGetDef( hReq, "booking_id", "" ) 
    cStatus    := Upper( hb_HGetDef( hReq, "payment_status", "OPEN" ) )
    
    IF !Empty( cReference ) .AND. cStatus == "PAID"
        // Buchung heraussuchen und als BEZAHLT markieren!
        USE ( "X:\xwhdaten\DATAWIN\BELEGUNG.DBF" ) NEW ALIAS ZPLAN SHARED
        SET ORDER TO TAG "BUCHUNGSNR"
        
        IF ZPLAN->( DbSeek( cReference ) )
            IF ZPLAN->( RLock() )
                REPLACE ZPLAN->FIXBUCHUNG WITH "BEZAHLT"
                ZPLAN->( DbCommit() )
                ZPLAN->( DbUnlock() )
            ENDIF
        ENDIF
        ZPLAN->( dbCloseArea() )
    ENDIF

    RETURN hb_jsonEncode({ "success" => .T., "message" => "Payment processed" })

ENDIF

// Unbekannter Provider
RETURN hb_jsonEncode({ "success" => .F., "error" => "Unknown Provider" })

//-- HARBOURINO INBOUND_WEBHOOK End --//
<?php
// Dies ist die Datei, die MessageBird oder Mollie aufruft!
$payload = file_get_contents('php://input');
$data = json_decode($payload, true);

// 1. Sicherheit: Prüfen ob das Passwort/Secret von MessageBird stimmt
if ($_SERVER['HTTP_X_MESSAGEBIRD_SIGNATURE'] !== 'DEIN_GEHEIMES_PASSWORT') {
    http_response_code(403);
    exit('Go away!');
}

// 2. Wir formen das Paket leicht um, damit Harbour es leichter hat
$harbourRequest = [
    "provider" => "MESSAGEBIRD",
    "sender_address" => $data['contact']['msisdn'], // Die Handynummer
    "message_text" => $data['message']['text']
];

// 3. Wir schicken es intern weiter an Harbour (Port 9090)
$msUrl = 'http://127.0.0.1:9090/inbound_msg';
$ctx = stream_context_create(['http' => ['method' => 'POST', 'content' => json_encode($harbourRequest)]]);
$res = file_get_contents($msUrl, false, $ctx);

echo "OK"; // Provider ist glücklich und beendet die Verbindung
?>

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Best Practices for modern Web/DBF integrations: Cloudflared, Mollie, MessageBird?
Posted: Sat Mar 07, 2026 09:28 AM

Dear Otto,

Has anyone already written integration classes for Mollie or MessageBird/Brevo in Harbour that they could share, or would you be interested in joining forces to build a stable class for these specific providers?

I am sure that Antigravity may build it in just a while :wink:

regards, saludos

Antonio Linares
www.fivetechsoft.com

Continue the discussion