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 refundId 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
/Optional
Description
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

FieldTypeRequired/
Optional
Description
targetAudienceStringOptionalTailors 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
userLanguageStringRequiredLanguage used by the user/operator.
agentPartnerIdStringRequiredUnique agent or partner identifier.
posIdStringOptionalPoint of sale identifier of the client performing the API Call
operatorIdStringOptionalOperator 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/
Optional
Description
transactionIdStringRequiredUnique identifier for the transaction resource.



Request body

FieldTypeRequired/
Optional
Description
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: 30
RequiredResidence address line 1
receiver.address.line2String
Min length: 0
Max length: 30
OptionalResidence address line 2 (if applicable)
receiver.address.line3String
Min length: 0
Max length: 30
OptionalResidence address line 3 (if applicable)
receiver.address.cityString
Min length: 1
Max length: 20
RequiredCity of residence
receiver.address.countrySubdivisionCodeString
Length: 6
OptionalState/province of residence
receiver.address.countryCodeString
Length: 3
RequiredCountry of residence (ISO Alpha-3 Code)
receiver.address.postalCodeString
Min length: 2
Max length: 10
OptionalPostal code/ZIP code of residence
receiver.mobilePhone.numberString
Min length: 5
Max length: 14
OptionalPhone number
receiver.mobilePhone.countryDialCodeString
Min length: 1
Max length: 3
OptionalCountry calling code (ISO alpha-3 code)
receiver.emailString
Min length: 1
Max length: 255
OptionalEmail 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: 6
OptionalLanguage ISO Alpha-3 code
receiver.personalDetails.genderCodeStringOptionalGender (Enumerated value)
receiver.personalDetails.dateOfBirthString
Length: 10
RequiredDate of birth (YYYY-MM-DD)
receiver.personalDetails.birthCityString
Min length: 0
Max length: 20
OptionalCity of birth
receiver.personalDetails.birthCountryCodeString
Max Length: 3
RequiredCountry 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: 3
OptionalOccupation/Employment (Enumerated value)
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: 3
OptionalCountry of citizenship (ISO alpha-3 code)
receiver.personalDetails.nationalityCountryCodeString
Min Length: 3
Max Length: 3
OptionalCountry of citizenship (ISO alpha-3 code)
receiver.primaryIdentification.typeCodeStringRequiredType of identification document (Enumerated value)
receiver.primaryIdentification.idString
Max length: 30
RequiredIdentification document number
receiver.primaryIdentification.issueCountrySubdivisionCodeString
Max length: 6
OptionalIssuing state/province of identification document
receiver.primaryIdentification.issueCountryCodeString
Max Length: 3
RequiredIssuing country of identification document
receiver.primaryIdentification.expirationYearString
Length: 4
Format: YYYY
OptionalExpiration year of identification document (YYYY)
receiver.primaryIdentification.expirationMonthString
Length: 4
Format: MM
OptionalExpiration month of identification document (MM)
receiver.primaryIdentification.expirationDayString
Length: 4
Format: DD
OptionalExpiration month of identification document (DD)
receiver.primaryIdentification.issueAuthorityString
Min length: 0
Max length: 30
OptionalIssuing authority of identification document
<code>receiver.primaryIdentification.issueCityString
Min length: 0
Max length: 20
OptionalIssuing city of identification document
receiver.primaryIdentification.issueYearString
Length: 4
Format: YYYY
OptionalIssuing year of identification document (YYYY)
receiver.primaryIdentification.issueMonthString
Length: 4
Format: MM
OptionalIssuing month of identification document (MM)
receiver.primaryIdentification.issueDayString
Length: 4
Format: DD
OptionalIssuing day of identification document (DD)
receiver.secondaryIdentification.typeCodeString
Max length: 3
RequiredType of identification document (Enumerated value)
receiver.secondaryIdentification.idString
Max length: 30
RequiredIdentification document number
receiver.secondaryIdentification.issueCountrySubdivisionCodeString
Max length: 6
OptionalIssuing state/province of identification document
receiver.secondaryIdentification.issueCountryCodeString
Max length: 3
RequiredIssuing country of identification document
receiver.secondaryIdentification.expirationYearString
Length: 4
Format: YYYY
OptionalExpiration year of identification document (YYYY)
receiver.secondaryIdentification.expirationMonthString
Length: 4
Format: MM
OptionalExpiration month of identification document (MM)
receiver.secondaryIdentification.expirationDayString
Length: 4
Format: DD
OptionalExpiration month of identification document (DD)
receiver.secondaryIdentification.issueAuthorityString
Min length: 0
Max length: 30
OptionalIssuing authority of identification document
receiver.secondaryIdentification.issueCityString
Min length: 0
Max length: 20
OptionalIssuing city of identification document
receiver.secondaryIdentification.issueYearString
Length: 4
Format: YYYY
OptionalIssuing year of identification document (YYYY)
receiver.secondaryIdentification.issueMonthString
Length: 4
Format: MM
OptionalIssuing month of identification document (MM)
receiver.secondaryIdentification.issueDayString
Length: 4
Format: DD
OptionalIssuing day of identification document (DD)
receiver.additionalAddress.typeStringOptionalType of additional address (Enumerated values)
receiver.additionalAddress.line1String
Min length: 5
Max length: 30
RequiredResidence address line 1
receiver.additionalAddress.line2String
Min length: 0
Max length: 30
OptionalResidence address line 2 (if applicable)
receiver.additionalAddress.line3String
Min length: 0
Max length: 30
OptionalResidence address line 3 (if applicable)
receiver.additionalAddress.cityString
Min length: 0
Max length: 20
RequiredCity of residence
receiver.additionalAddress.countrySubdivisionCodeString
Max Length: 6
OptionalState/province of residence
receiver.additionalAddress.countryCodeString
Max length: 3
RequiredCountry of residence (ISO Alpha-3 Code)
receiver.additionalAddress.postalCodeString
Min length: 2
Max length: 6
OptionalPostal code/ZIP code of residence
receiver.additionalFamilyNames.typeStringOptionalType of family name (Enumerated values)
receiver.additionalFamilyNames.firstNameString
Min length: 0
Max length: 20
OptionalFirst name
receiver.additionalFamilyNames.middleNameString
Min length: 0
Max length: 20
OptionalMiddle name (if applicable)
receiver.additionalFamilyNames.lastNameString
Min length: 0
Max length: 30
OptionalLast name
receiver.additionalFamilyNames.secondLastNameString
Min length: 0
Max length: 30
OptionalSecond last name
receiver.profileIdStringOptionalConsumer's unique identifier
receiver.additionalDetailsDynamicOptionalDynamic field/key value
relationshipToSenderString
Max length: 30
OptionalReceiver’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: 50
OptionalReceiver’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: 50
OptionalReceiver’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



Response fields

FieldTypeRequired/
Optional
Description
readyForCommitBooleanRequiredIndicates whether the transaction can proceed to commit
transactionIdString
Max length: 36
RequiredUnique identifier for the transaction resource