Search by

smart-dato / sf-express-sdk

smart-dato

SF Express international open API SDK for Laravel

Package info

github.com/smart-dato/sf-express-sdk

pkg:composer/smart-dato/sf-express-sdk

Fund package maintenance!

SmartDato

Statistics

Installs: 4 401

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.0.6 2026-04-01 11:28 UTC

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

A Laravel package for the SF Express international open API. It creates shipments, queries order details and fetches tracking, handling the API's AES message encryption and request signing for you.

Requirements

  • PHP 8.2+
  • Laravel 10 – 13
  • The openssl PHP extension

Installation

composer require smart-dato/sf-express-sdk

Usage

Construct the client with your SF Express base URL and credentials:

use SmartDato\SfExpress\SfExpress;

$sf = new SfExpress(
    baseUrl: 'https://api-ifsp-sit.sf.global', // SF's SIT (sandbox) environment
    appKey: 'your-app-key',
    appSecret: 'your-app-secret',
    encodingAesKey: 'your-encoding-aes-key',
);

The constructor authenticates immediately — it calls /openapi/api/token and throws SfExpressGenericException if SF rejects the credentials. Build the client when you are about to make calls, not eagerly at boot.

A config file maps SF_EXPRESS_API_KEY and SF_EXPRESS_SECRET to sf-express-sdk.app.key and .secret, but it is only consulted for the token request. The base URL has no config fallback, and the app key is also needed for signing, so pass all four arguments explicitly. For the same reason the registered SfExpress facade cannot be used as-is.

Every method takes the request as a JSON string. The payload classes build that string for you with toJson().

Create a shipment

Sends an IUOP_CREATE_ORDER message.

use SmartDato\SfExpress\Enums\Shipment\CurrencyEnum;
use SmartDato\SfExpress\Enums\Shipment\InterProductCodeEnum;
use SmartDato\SfExpress\Payloads\ParcelInfoPayload;
use SmartDato\SfExpress\Payloads\PaymentInfoPayload;
use SmartDato\SfExpress\Payloads\ShipmentPayload;
use SmartDato\SfExpress\Payloads\ShippingPartyPayload;

$payload = new ShipmentPayload(
    customerCode: 'your-customer-code',
    interProductCode: InterProductCodeEnum::INT0014,
    parcelQuantity: 1,
    customerOrderNumber: 'order-1001',
    parcels: [
        new ParcelInfoPayload(
            amount: 25.0,
            name: 'Gloves',
            eName: 'Gloves',
            originCountry: 'CN',
            quantity: 1,
            unit: 'your-unit',
        ),
    ],
    paymentInfo: new PaymentInfoPayload(
        payMethod: 'your-pay-method',
        payMonthCard: 'your-monthly-account',
        taxPayMethod: 'your-tax-pay-method',
        taxPayMonthCard: '',
    ),
    receiverInfo: new ShippingPartyPayload(
        address: 'Werner-Heisenberg-Allee 25',
        regionSecond: '106A',
        contact: 'Jane Doe',
        country: 'DE',
        postCode: '80939',
        regionFirst: 'München',
        phoneNumber: '+49 89 000000',
        email: 'jane@example.com',
    ),
    senderInfo: new ShippingPartyPayload(
        address: 'Bismarckstraße 122',
        regionSecond: '11A',
        contact: 'Sender GmbH',
        country: 'DE',
        postCode: '51373',
        regionFirst: 'Leverkusen',
        phoneNumber: '+49 214 000000',
    ),
    declaredValue: 25.0,
    declaredCurrency: CurrencyEnum::EUR,
    parcelTotalWeight: 0.4,
    parcelWeightUnit: 'kg',
    parcelTotalLength: 30,
    parcelTotalWidth: 20,
    parcelTotalHeight: 5,
);

$result = $sf->createShipment($payload->toJson());

ShipmentPayload also accepts pickup, customs, extended-info and added-service details — see its constructor for the full list.

Query shipment details

Sends an IUOP_QUERY_ORDER message.

use SmartDato\SfExpress\Payloads\ShipmentDetailsPayload;

$details = $sf->getShipmentDetails(
    (new ShipmentDetailsPayload(customerCode: 'your-customer-code', sfWaybillNumber: 'SF0000000000000'))->toJson()
);

Track a shipment

Sends a GTS_QUERY_TRACK message.

use SmartDato\SfExpress\Payloads\TrackingPayload;

$tracking = $sf->getTrackingStatus(
    (new TrackingPayload(sfWaybillNumbers: ['SF0000000000000'], phoneNumber: '0000'))->toJson()
);

Each method returns the decrypted response decoded into an array. A non-zero apiResultCode from SF raises SfExpressGenericException with the code and message.

Testing

composer test

The tests that call SF's sandbox are skipped by default, since they need real credentials.

Changelog

Please see CHANGELOG for more information on what has changed recently.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.