Skip to main content

Goods Stock Transfer (T139)

Transfer inventory quantities between registered branches for the same taxpayer. This endpoint supports both standard goods and fuel products, with optional rollback on error handling. Request and response are encrypted.


Endpoint Overview​

PropertyValue
Interface CodeT139
Request Encryptedβœ… Yes
Response Encryptedβœ… Yes
Request Body{ "goodsStockTransfer": {...}, "goodsStockTransferItem": [...] }
Response FormatJSON Array

Flow Description​

  1. Client submits transfer request with source/destination branch IDs and item list.
  2. Server validates branch ownership, stock availability, and field constraints.
  3. Server processes transfer:
    • Decrements stock at sourceBranchId
    • Increments stock at destinationBranchId
    • For fuel products: validates sourceFuelTankId/destinationFuelTankId mappings
  4. Server returns per-item status with returnCode and returnMessage.
  5. If rollBackIfError=1 and any item fails, entire transaction is rolled back.

πŸ’‘ Tip: Call T138 (Get All Branches) first to retrieve valid branchId values. For fuel products, ensure tank IDs match the branch via T169 before transferring.


try {
// Call T139: Goods Stock Transfer
$transferData = [
'goodsStockTransfer' => [
'sourceBranchId' => '206637525568955296',
'destinationBranchId' => '206637528324276772',
'transferTypeCode' => '101', // Out of Stock Adjust
'remarks' => 'Monthly stock rebalance',
'rollBackIfError' => '1',
'goodsTypeCode' => '101' // 101=Goods, 102=Fuel
],
'goodsStockTransferItem' => [
[
'commodityGoodsId' => '287700992426868373',
// OR use goodsCode if commodityGoodsId unavailable:
// 'goodsCode' => 'PROD_001',
'measureUnit' => '101',
'quantity' => '100',
'remarks' => 'Transfer from warehouse A to B',
// For fuel products only:
// 'sourceFuelTankId' => '568654903587001037',
// 'destinationFuelTankId' => '568654903587001038'
]
]
];

$response = $client->transferStock($transferData);
$items = $response['data']['content'] ?? $response;

if (is_array($items)) {
foreach ($items as $item) {
if (($item['returnCode'] ?? '00') === '00') {
echo "βœ… Item transferred: {$item['commodityGoodsId']}\n";
} else {
echo "❌ Item failed: {$item['returnCode']} - {$item['returnMessage']}\n";
}
}
}

} catch (\UraEfrisSdk\Exceptions\APIException $e) {
echo "❌ Transfer failed: " . $e->getMessage() . "\n";
echo " Return Code: " . $e->getReturnCode() . "\n";
}

Request Structure​

{
"data": {
"content": "BASE64_ENCRYPTED_PAYLOAD",
"signature": "JKQWJK34K32JJEK2JQWJ5678",
"dataDescription": {
"codeType": "1",
"encryptCode": "2",
"zipCode": "0"
}
},
"globalInfo": {
"interfaceCode": "T139",
"appId": "AP04",
"version": "1.1.20191201",
"tin": "1000029771",
"deviceNo": "TCS9e0df01728335239",
"taxpayerID": "1"
}
}

Request Fields (Encrypted Payload)​

GoodsStockTransfer Object​

FieldRequiredTypeLengthDescription
sourceBranchIdβœ… YesString≀18Source branch identifier (must belong to current taxpayer)
destinationBranchIdβœ… YesString≀18Destination branch identifier (must belong to current taxpayer; cannot equal sourceBranchId)
transferTypeCodeβœ… YesString≀20101=Out of Stock Adjust, 102=Error Adjust, 103=Others (multiple values separated by commas, e.g., "101,102")
remarks❌ NoString≀1024Transfer description; required if transferTypeCode includes 103
rollBackIfError❌ NoString (1)10=Continue on error, 1=Rollback entire transaction on first error (default: 0)
goodsTypeCode❌ NoString (3)3101=Standard Goods, 102=Fuel Products (default: 101)

GoodsStockTransferItem Array (One or More Required)​

FieldRequiredTypeLengthDescription
commodityGoodsId⚠️ ConditionalString≀18Goods identifier from T130; required if goodsCode is empty
goodsCode⚠️ ConditionalString≀50Goods code from T130; required if commodityGoodsId is empty
measureUnit❌ NoString (3)3Unit of measure code from T115 rateUnit; must match maintained commodity unit
quantityβœ… YesNumber≀18Transfer quantity; must be positive and not exceed available stock at source
remarks❌ NoString≀1024Item-level transfer notes
sourceFuelTankId❌ NoString≀18Fuel only: Source tank identifier (must match branch and goods)
destinationFuelTankId❌ NoString≀18Fuel only: Destination tank identifier (must match branch and goods)

πŸ’‘ Tip: Either commodityGoodsId OR goodsCode must be provided per itemβ€”never both empty. For fuel products (goodsTypeCode=102), tank IDs are mandatory and must be validated via T169.


Response Structure​

{
"data": {
"content": [
{
"commodityGoodsId": "287700992426868373",
"goodsCode": "287700992426",
"measureUnit": "101",
"quantity": "100",
"remarks": "Transfer from warehouse A to B",
"sourceFuelTankId": "568654903587001037",
"destinationFuelTankId": "568654903587001038",
"returnCode": "00",
"returnMessage": "SUCCESS"
}
]
},
"globalInfo": {
"interfaceCode": "T139",
"returnStateInfo": {
"returnCode": "00",
"returnMessage": "SUCCESS"
}
}
}

Response Fields​

Per-Item Response Array​

FieldRequiredTypeDescription
commodityGoodsIdβœ… YesString (18)Goods identifier (echoed from request)
goodsCodeβœ… YesString (50)Goods code (echoed from request)
measureUnitβœ… YesString (3)Unit of measure (echoed from request)
quantityβœ… YesNumberTransferred quantity (echoed from request)
remarks❌ NoStringItem remarks (echoed from request)
sourceFuelTankId❌ NoString (18)Source tank ID (fuel products only)
destinationFuelTankId❌ NoString (18)Destination tank ID (fuel products only)
returnCodeβœ… YesString (10)Item-level status code (00=success, else error)
returnMessageβœ… YesStringHuman-readable status message

Return Codes​

CodeMessageDescription
00SUCCESSTransfer completed successfully
99Unknown errorGeneric server error
400Device does not existdeviceNo not registered for this TIN
402Device key expiredDevice credentials expired; re-run T102
403Device status is abnormalDevice blocked or suspended
2141destinationBranchId cannot be empty!Missing destination branch
2142destinationBranchId:Byte length cannot be greater than 18!Destination branch ID too long
2143sourceBranchId does not belong to current taxpayer!Source branch not owned by TIN
2144destinationBranchId does not belong to current taxpayer!Destination branch not owned by TIN
2145sourceBranchId and destinationBranchId cannot be the same!Self-transfer not allowed
2146transferTypeCode:cannot be empty!Missing transfer type
2148transferTypeCode: invalid field value!Invalid transfer type code
2149remarks:cannot be empty!Remarks required when transferTypeCode=103
2152transferred quantity exceeds the original stockInsufficient stock at source branch
2153sourceBranchId cannot be emptyMissing source branch
2194goodsCode:cannot be empty!Both commodityGoodsId and goodsCode empty
2196commodityGoodsId and goodsCode cannot be empty at the same time!At least one identifier required
2242goodsStockTransferItem can not be empty!No items provided for transfer
2243measureUnit: inconsistent with the maintained commodity unit!Unit mismatch with T130 registration
2890-2892rollBackIfError validation errorsInvalid rollback flag format/value
3008-3015Fuel tank validation errorsTank ID mismatches, product type conflicts

πŸ’‘ Tip: A returnCode of 00 per item indicates successful transfer. If rollBackIfError=1, any non-00 code triggers rollback of all items.


Common Use Cases​

  1. Inter-Branch Stock Rebalancing
    Move excess inventory from overstocked branches to locations with higher demand.

  2. Error Correction Transfers
    Use transferTypeCode=102 to correct stock discrepancies identified during audits.

  3. Fuel Depot Management
    Transfer fuel between tanks/branches with tank-specific tracking via sourceFuelTankId/destinationFuelTankId.

  4. Rollback-Safe Bulk Transfers
    Set rollBackIfError=1 for critical transfers where partial completion is unacceptable.

  5. Multi-Item Consolidation
    Transfer multiple SKUs in a single API call to reduce network overhead and ensure atomicity.

  6. Compliance Auditing
    Log all transfer requests with remarks for traceability in stock movement reports.


Integration Checklist​

βœ… Call T138 first to validate sourceBranchId and destinationBranchId belong to taxpayer
βœ… Ensure sourceBranchId β‰  destinationBranchId to avoid validation errors
βœ… Provide either commodityGoodsId OR goodsCode per item (never both empty)
βœ… Validate measureUnit matches T115 rateUnit and T130 commodity registration
βœ… For fuel products (goodsTypeCode=102): validate tank IDs via T169 before transfer
βœ… Check available stock at source branch before submitting (avoid 2152 errors)
βœ… Use rollBackIfError=1 for critical transfers where atomicity is required
βœ… Parse per-item returnCode in responseβ€”partial success is possible if rollback disabled
βœ… Log transfer remarks and transferTypeCode for audit trail compliance
βœ… Re-query stock levels via T128/T147 post-transfer to confirm successful movement