PUT Update a Transaction

PUT /payout/v1/transactions/{transactionId}

Development Guide

The 'Update a Transaction' endpoint determines what information to collect from the consumer, validates the data for compliance purposes and updates the transactionId resource with the data collected.


1. Prepare headers, authentication & parameters

The application must call the 'Update a Transaction' endpoint with a PUT HTTP method, providing the OAuth access_token , the transactionId as a path parameter and all other required headers.


Note:

  • MoneyGram uses the OAuth 2.0 framework. The application must use their OAuth client credentials to generate an access_token by calling the Get Access Token endpoint. The token is valid for 1 hour and must be passed as a header value in all subsequent API HTTP calls. Learn More
  • The transactionId should have been returned on the previous Retrieve a tTansaction endpoint response.

🚀

Launch Code Example:




2. Provide payoutId in the request body:

To Update a Transaction, it is required to pass the payoutId which was returned on the previous Retrieve a Transaction API response and all other required fields.


🚀

Launch Code Example:




3. Provide request body:

The request body must include the payoutId that was generated and returned in the previous 'Retrieve a transaction’ endpoint and at a minimum collect the receiver.address, receiver.primaryIdentification and receiver.dateOfBirth for MoneyGram to perform a real-time validation and compliance screening.


Note:

  • To understand a full list of REQUIRED and OPTIONAL fields, the application can call the Retrieve transactional send fields API. Learn More
  • Additional data collection may be required based on the receiveAmount and destinationCountryCode.

🚀

Launch Code Example:




4. Make a request and handle response

The application must call the 'Update a transaction' endpoint with a PUT HTTP method and be able to handle the following response scenarios:


  • Success | Parse the Response | 200 OK HTTP Status | "readyForCommit": true When the 'Update a transaction' endpoint responds with a 200 HTTP Status the response will return the following fields: readyForCommit, and transactionId.

  • Failed | Handle the Error | 400 Bad Request HTTP Status When the 'Update a transaction' endpoint responds with 400 HTTP Status, specific error code/s will be returned with an array of offending fields. The application will need to resolve these errors and resubmit the transaction for validation.

Note:

  • In some scenario's, enhanced due diligence is need to be undertaken on the consumer. A specific error code will be returned and an array of offending fields. The fields/values need to be provided and resubmitted on the Update API for further checks
  • In some cases, send or receive side taxes may be applied. Learn More
  • Only when the "readyForCommit": true, is returned can the application proceed to "Commit a transaction" API and execute the payout of funds.

🚀

Launch Code Example:

.





5. You're Done! Proceed to the 'Commit a transaction API'

The application can call the Commit endpoint to execute the payout when a 200 HTTP Success Status is returned from the 'Update a transaction' response. The application must use the same transactionId on the subsequent Commit API by providing it as a path parameter. The Commit endpoint is the final API call and will execute the payout.


Note:

  • To execute the refund, the transactionId returned in the payload must be persisted and used as a path parameter on subsequent 'Commit a Transaction' API.
  • To execute the refund, the payoutId returned in the payload must be persisted and used as in the request body of the subsequent 'Commit a Transaction' API.




Business Rules to Code


🔎
  1. Making multiple PUT requests to Update the transactionId: if there are any changes needed for consumer data after the Update a transaction endpoint responds, the application should call the Update endpoint to using the same transactionId and payoutId to provide new consumer/transactional data.

  2. **Enumerated fields: **For all Enumerated Fields (some examples below), agent application must use the valid enumerations returned from the enumerations API response and allow only valid values to be selected. Learn More

  3. *Pre-disclosure: It is regulatory requirement to show pre-disclosure on every transfer, in every country and for every service option. Learn More



Code Examples


const axios = require('axios');
const { v4: uuidv4 } = require('uuid');

const updateTransaction = async () => {

    // Step 1: Read configuration values with upmost security
    const token = "your_access_token_from_oauth_response"
    // For production - api.moneygram.com & For test - sandboxapi.moneygram.com
    const transactionId = "current_transaction_id";
    const host = "sandboxapi.moneygram.com";
    const url = 'https://' + host + '/payout/v1/transactions/' + transactionId;

    // Step 2: Create the PUT request headers, params & body

    const headers = {
        'Content-Type': 'application/json',
        'X-MG-ClientRequestId': uuidv4(), // New UUID for each request tracing
        'Authorization': 'Bearer ' + token,
    };

    const params = {
        agentPartnerId: "your_partner_id",
        targetAudience: "AGENT_FACING",
        userLanguage: "en-US",
    }

    const request = {
        payoutId: "current_payout_id", // generated during the retrieve transaction
        receiver: {
            address: {
                line1: "100 Main St",
                city: "Springfield",
                countrySubdivisionCode: "US-TX",
                countryCode: "USA",
                postalCode: "55001"
            },
            mobilePhone: {
                number: "5551231234",
                countryDialCode: "1"
            },
            personalDetails: {
                dateOfBirth: "10-10-1998",
                birthCountryCode: "USA"
            },
            primaryIdentification: {
                typeCode: "DRV",
                id: "123456789",
                issueCountrySubdivisionCode: "US-TX",
                issueCountryCode: "USA",
            }
        }
    }

    try {
        // Step 3: Send the request and obtain the response
        axios.put(url, request, { params, headers })
            .then(function (response) {
                // Step 4: Parse the success response and process further
                // Verify readyForCommit is true, if yes, transaction is ready to commit
                console.log(JSON.stringify(response.data, null, 2))
            })
            .catch(function (error) {
                // Step 5: Parse the error response and handle the errors
                if (error.response) {
                    console.log('Response status:', error.response.status);
                    console.log('Response body:', error.response.data);
                } else {
                    // TODO: handle generic errors
                    console.error('Error:', error.message);
                }
            });
    } catch (error) {
        // TODO: handle exception
        console.error('Error:', error.message);
    }
};

updateTransaction();
import requests
import uuid
import json

def update_transaction():
    # Step 1: Read configuration values with upmost security
    token = "your_access_token_from_oauth_response"
    # For production - api.moneygram.com & For test - sandboxapi.moneygram.com
    transactionId = "current_transaction_id";
    host = "sandboxapi.moneygram.com";
    url = 'https://' + host + '/payout/v1/transactions/'+ transactionId;

    # Step 2: Create the PUT request headers, params & body

    headers = {
        'Content-Type': 'application/json',
        'X-MG-ClientRequestId': str(uuid.uuid4()), # New UUID for each request tracing
        'Authorization': 'Bearer ' + token,
    }

    params = {
        'agentPartnerId': 'your_partner_id',
        'targetAudience': 'AGENT_FACING',
        'userLanguage': 'en-US',
    }

    request = {
        'payoutId': "current_payout_id", # generated during the retrieve transaction
        'receiver': {
            'address': {
                'line1': "100 Main St",
                'city': "Springfield",
                'countrySubdivisionCode': "US-TX",
                'countryCode': "USA",
                'postalCode': "55001"
            },
            'mobilePhone': {
                'number': "5551231234",
                'countryDialCode': "1"
            },
            'personalDetails': {
                'dateOfBirth': "10-10-1998",
                'birthCountryCode': "USA"
            },
            'primaryIdentification': {
                'typeCode': "DRV",
                'id': "123456789",
                'issueCountrySubdivisionCode': "US-TX",
                'issueCountryCode': "USA",
            }
        }
    }

    try:
        # Step 3: Send the request and obtain the response
        response = requests.put(url, json=request, headers=headers)

        # Step 4: Parse the success response and process further
        if response.status_code == 200:
            parsed_response = json.dumps(json.loads(response.text), indent=2)
            print(parsed_response)
        else:
            # Step 5: Parse the error response and handle the errors
            print("Request failed with status code:", response.status_code)
            print(json.dumps(json.loads(response.text), indent=2))

    except requests.exceptions.RequestException as e:
        # Print any error that occurred during the request
        # TODO: handle exception
        print("An error occurred:", e)

update_transaction()
package payout;

import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonWriter;
import java.io.StringWriter;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.UUID;

public class UpdateTransaction {

    public static void main(String[] args) {
        // Step 1: Read configuration values with upmost security
        String token = "your_access_token_from_oauth_response";

        // For production - api.moneygram.com & For test - sandboxapi.moneygram.com
        String host = "sandboxapi.moneygram.com";
        String transactionId = "current_transaction_id";
        String uri = "https://" + host + "/payout/v1/transactions/" + transactionId;

        // Step 2: Create the PUT request headers & body

        // Create a JSON object
        JsonObjectBuilder receiverBuilder = Json.createObjectBuilder()
                .add("address", Json.createObjectBuilder().add("line1", "100 Main St").add("city", "Springfield")
                .add("countryCode", "USA").add("countrySubdivisionCode", "US-TX").add("postalCode", "55001"))
                .add("mobilePhone", Json.createObjectBuilder().add("number", "5551231234").add("countryDialCode", "1"))
                .add("personalDetails", Json.createObjectBuilder().add("dateOfBirth", "10-10-1998").add("birthCountryCode", "USA"))
                .add("primaryIdentification", Json.createObjectBuilder().add("typeCode", "DRV").add("id", "123456789").add("issueCountryCode", "USA").add('issueCountrySubdivisionCode': "US-TX"));
        JsonObjectBuilder requestBuilder = Json.createObjectBuilder()
                .add("payoutId", "current_payout_id")
                .add("agentPartnerId", "your_partner_id")
                .add("targetAudience", "AGENT_FACING")
                .add("userLanguage", "en-US")
                .add("receiver", receiverBuilder)

        JsonObject jsonObject = requestBuilder.build();
        // Create a StringWriter to write the JSON string
        StringWriter stringWriter = new StringWriter();
        try (JsonWriter jsonWriter = Json.createWriter(stringWriter)) {
            jsonWriter.writeObject(jsonObject);
        }
        // Get the JSON string from the StringWriter
        String jsonString = stringWriter.toString();

        HttpClient httpClient = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(uri))
                .PUT(HttpRequest.BodyPublishers.ofString(jsonString))
                .setHeader("Authorization", "Bearer " + token)
                .setHeader("X-MG-ClientRequestId", String.valueOf(UUID.randomUUID()))
                .build();

        try {
            // Step 3: Send the request and obtain the response
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

            // Retrieve the status code and body from the response
            int statusCode = response.statusCode();

            // Step 4: Parse the success response and process further
            if (statusCode == 200) {
                String responseBody = response.body();
                System.out.println(responseBody);
            } else {
                // Step 5: Parse the error response and handle the errors
                String responseBody = response.body();
                System.out.println(responseBody);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // TODO: handle exception
        }
    }
}




Support APIs

To make your development easier, MoneyGram has provided a Reference Data APIs Module that can be queried to provide a list of supported fields, values and associated meta-data to use in your integration.

NameHTTP MethodEndpointsDescription
Retrieve CountriesGET/reference-data/v1/CountryRetrieves supported values and metadata for countries
Retrieve Countries ISO3GET/reference-data/v1 /countries/{iso3Code}Retrieves supported values and metadata for countries by ISO 3 Code
Retrieve CurrenciesGET/reference-data/v1/currenciesRetrieves supported values and metadata for currencies
Retrieve EnumerationsGET/reference-data/v1/enumerationsRetrieves enumerated values for fields
Retrieve Identification DocumentsGET/reference-data/v1/identification-DocumentsRetrieves required fields for identification documents
Retrieve Service OptionsGET/reference-data/v1/payout-optionsRetrieves supported values and metadata for Service Options



API Structure


Header parameters

NameTypeRequired /OptionalDescription
X-MG-ClientRequestIdStringOptionalClient request ID that can be passed by the client application. Client request ID must be unique within a single session for unique requests. This attribute can be used for ensuring idempotent request processing for some APIs. MoneyGram recommends using a UUID for the value of this field.
X-MG-SessionIdStringConditionally RequiredA GUID MoneyGram generates for correlating multiple calls within a transaction session. Note: The X-MG-SessionId is not required if the payoutId is passed in the request body.
X-MG-ConsumerIPAddressStringOptionalIP address of the system initiating the session.



Query parameters

Field

Type

Required/ Optional

Description

targetAudience

String

Optional

Tailors MoneyGram’s error messages and field metadata to an in-store, digital or crypto consumer. (Enumerated value)
NOTE: For a full list of accepted target audience values. See the TARGET_AUDIENCE enumeration from the Reference Data Enumerations endpoint

userLanguage

String

Required

Language used by the user/operator.

agentPartnerId

String

Required

Unique agent or partner identifier.

posId

String

Optional

Point of sale identifier of the client performing the API Call

operatorId

String Max length: 80

Required

Operator name or ID of the user performing the transaction. Name or ID must be populated from the agent/partner system and cannot be edited by the user.




Path parameters

FieldTypeRequired/ OptionalDescription
transactionIdStringRequiredUnique identifier for the transaction resource.



Request body

FieldTypeRequired/ OptionalDescription
payoutIdStringConditionally RequiredUnique identifier for the transaction session Note: The payoutId is not required if the X-MG-SessionId is passed as a header parameter.
receiver.address.line1String Min length: 5 Max length: 30RequiredResidence address line 1
receiver.address.line2String Min length: 0 Max length: 80OptionalResidence address line 2 (if applicable)
receiver.address.line3String Min length: 0 Max length: 80OptionalResidence address line 3 (if applicable)
receiver.address.cityString Min length: 1 Max length: 20RequiredCity of residence
receiver.address.countrySubdivisionCodeString Length: 6OptionalState/province of residence
receiver.address.countryCodeString Length: 3RequiredCountry of residence (ISO Alpha-3 Code)
receiver.address.postalCodeString Min length: 2 Max length: 10OptionalPostal code/ZIP code of residence
receiver.mobilePhone.numberString Min length: 5 Max length: 14OptionalPhone number
receiver.mobilePhone.countryDialCodeString Min length: 1 Max length: 3OptionalCountry calling code (ISO alpha-3 code)
receiver.emailString Min length: 1 Max length: 255OptionalEmail address
receiver.notificationPreferences.typeStringOptionalType of notification content (Enumerated values)
receiver.notificationPreferences.channelStringOptionalDelivery method of notification (Enumerated value)
receiver.notificationPreferences.optInBooleanOptionalFlag to declare consumer opts in to notification type and method
receiver.notificationLanguagePreferenceString Max length: 6OptionalLanguage ISO Alpha-3 code
receiver.personalDetails.genderCodeStringOptionalGender (Enumerated value)
receiver.personalDetails.dateOfBirthString Length: 10RequiredDate of birth (YYYY-MM-DD)
receiver.personalDetails.birthCityString Min length: 0 Max length: 20OptionalCity of birth
receiver.personalDetails.birthCountryCodeString Max Length: 3RequiredCountry of birth (ISO alpha-3 code) _NOTE: For a full list of accepted birth.CountryCodes see ‘Reference data API module’ and the countryInfo endpoint: _
receiver.personalDetails.citizenshipCountryCodeString Max Length: 3OptionalCitizenship Code (ISO alpha-3 code)
receiver.personalDetails.occupationCodeStringOptionalOccupation/Employment (Enumerated value) _NOTE: For a full list of accepted Occupation Codes. See the OCCUPATION enumeration from the Reference Data Enumerations endpoint _
receiver.personalDetails.politicalExposedPersonBooleanOptionalFlag to declare a Politically Exposed Person (PEP)
receiver.personalDetails.nationalityCountryCodeString Min Length: 3 Max Length: 3OptionalCountry of citizenship (ISO alpha-3 code)
receiver.primaryIdentification.typeCodeStringRequiredType of identification document (Enumerated value)
receiver.primaryIdentification.idString Max length: 30RequiredIdentification document number
receiver.primaryIdentification.issueCountrySubdivisionCodeString Max length: 6OptionalIssuing state/province of identification document
receiver.primaryIdentification.issueCountryCodeString Max Length: 3RequiredIssuing country of identification document
receiver.primaryIdentification.expirationYearString Length: 4 Format: YYYYOptionalExpiration year of identification document (YYYY)
receiver.primaryIdentification.expirationMonthString Length: 4 Format: MMOptionalExpiration month of identification document (MM)
receiver.primaryIdentification.expirationDayString Length: 4 Format: DDOptionalExpiration month of identification document (DD)
receiver.primaryIdentification.issueAuthorityString Min length: 0 Max length: 30OptionalIssuing authority of identification document
receiver.primaryIdentification.issueCityString Min length: 0 Max length: 20OptionalIssuing city of identification document
receiver.primaryIdentification.issueYearString Length: 4 Format: YYYYOptionalIssuing year of identification document (YYYY)
receiver.primaryIdentification.issueMonthString Length: 4 Format: MMOptionalIssuing month of identification document (MM)
receiver.primaryIdentification.issueDayString Length: 4 Format: DDOptionalIssuing day of identification document (DD)
receiver.secondaryIdentification.typeCodeString Max length: 3RequiredType of identification document (Enumerated value)
receiver.secondaryIdentification.idString Max length: 30RequiredIdentification document number
receiver.secondaryIdentification.issueCountrySubdivisionCodeString Max length: 6OptionalIssuing state/province of identification document
receiver.secondaryIdentification.issueCountryCodeString Max length: 3RequiredIssuing country of identification document
receiver.secondaryIdentification.expirationYearString Length: 4 Format: YYYYOptionalExpiration year of identification document (YYYY)
receiver.secondaryIdentification.expirationMonthString Length: 4 Format: MMOptionalExpiration month of identification document (MM)
receiver.secondaryIdentification.expirationDayString Length: 4 Format: DDOptionalExpiration month of identification document (DD)
receiver.secondaryIdentification.issueAuthorityString Min length: 0 Max length: 30OptionalIssuing authority of identification document
receiver.secondaryIdentification.issueCityString Min length: 0 Max length: 20OptionalIssuing city of identification document
receiver.secondaryIdentification.issueYearString Length: 4 Format: YYYYOptionalIssuing year of identification document (YYYY)
receiver.secondaryIdentification.issueMonthString Length: 4 Format: MMOptionalIssuing month of identification document (MM)
receiver.secondaryIdentification.issueDayString Length: 4 Format: DDOptionalIssuing day of identification document (DD)
receiver.additionalAddress.typeStringOptionalType of additional address (Enumerated values)
receiver.additionalAddress.line1String Min length: 5 Max length: 30RequiredResidence address line 1
receiver.additionalAddress.line2String Min length: 0 Max length: 30OptionalResidence address line 2 (if applicable)
receiver.additionalAddress.line3String Min length: 0 Max length: 30OptionalResidence address line 3 (if applicable)
receiver.additionalAddress.cityString Min length: 0 Max length: 20RequiredCity of residence
receiver.additionalAddress.countrySubdivisionCodeString Max Length: 6OptionalState/province of residence
receiver.additionalAddress.countryCodeString Max length: 3RequiredCountry of residence (ISO Alpha-3 Code)
receiver.additionalAddress.postalCodeString Min length: 2 Max length: 6OptionalPostal code/ZIP code of residence
receiver.additionalFamilyNames.typeStringOptionalType of family name (Enumerated values)
receiver.additionalFamilyNames.firstNameString Min length: 0 Max length: 20OptionalFirst name
receiver.additionalFamilyNames.middleNameString Min length: 0 Max length: 20OptionalMiddle name (if applicable)
receiver.additionalFamilyNames.lastNameString Min length: 0 Max length: 30OptionalLast name
receiver.additionalFamilyNames.secondLastNameString Min length: 0 Max length: 30OptionalSecond last name
receiver.profileIdStringOptionalConsumer's unique identifier
receiver.additionalDetailsDynamicOptionalDynamic field/key value
relationshipToSenderString Max length: 30OptionalReceiver’s relationship to sender based on (Enumerated Values) _NOTE: For a full list of accepted relationship to sender values. See the RELATIONSHP_TO_SNDR enumeration from the Reference Data Enumerations endpoint _
receivePurposeOfTransactionString Max length: 50OptionalReceiver’s purpose for the transaction (Enumerated Values) _NOTE: For a full list of accepted purpose of transaction values. See the PURPSE_OF_TRNSCTION enumeration from the Reference Data Enumerations endpoint _
intendedUseOfMGIServicesString Max length: 50OptionalReceiver’s intended use of MGI services (Enumerated Values) _NOTE: For a full list of accepted use of MGI services values. See the TYPICAL_USE_OF_MGI enumeration from the Reference Data Enumerations endpoint _
receipt.primaryLanguageStringOptionalPrimary receipt language of the transacting partner
receipt.secondaryLanguageStringOptionalSecondary receipt language of the transacting partner
receipt.imageStringOptionalReceipt image string of the transacting partner



Response fields

Field

Type

Required/ Optional

Description

readyForCommit

Boolean

Required

Indicates whether the transaction can proceed to commit

transactionId

String
Max length: 36

Required

Unique identifier for the transaction resource