MoneyCollect uses a Payment object to represent your intent to collect payment from a customer, tracking charge attempts and payment state changes throughout the process.
Handle any next actions
Add an endpoint on your server that creates a Payment. A Payment tracks the customer’s payment life cycle, keeping track of any failed payment attempts and ensuring the customer is only charged once. Return the Payment’s client secret in the response to finish the payment on the client.
packagecom.moneycollect.sample;importcom.alibaba.fastjson.JSONObject;importcom.moneycollect.Moneycollect;importcom.moneycollect.model.Payment;importcom.moneycollect.param.PaymentCreateParams;importlombok.Data;importjava.nio.file.Paths;importstaticspark.Spark.*;publicclassServer {privatestaticJSONObject json =newJSONObject(); @DatastaticclassCreatePaymentResponse {privateString id;privateString clientSecret;publicCreatePaymentResponse(String id,String clientSecret) {this.id= id;this.clientSecret= clientSecret; } }publicstaticvoidmain(String[] args) {port(5050);staticFiles.externalLocation(Paths.get("public").toAbsolutePath().toString());// This is a sample test API key.MoneyCollect.apiKey="test_pr_K***";post("/create-payment", (request, response) -> {response.type("application/json");PaymentCreateParams params =PaymentCreateParams.builder().setAmount(14*100L).setCurrency("USD").setOrderNo("MC"+System.currentTimeMillis()).build();Payment payment =Payment.create(params); CreatePaymentResponse paymentResponse = new CreatePaymentResponse(payment.getId(),payment.getClientSecret());
returnjson.toJSONString(paymentResponse); }); }}
3. Build a checkout page on the client
Load MoneyCollect.js Use McPayment.js to remain PCI compliant by ensuring that payment details are sent directly to MoneyCollect without hitting your server. Always load MoneyCollect.js from static.moneycollect.com to remain compliant. Don’t include the script in a bundle or host it yourself.
Define the payment form
Add an empty placeholder div to your checkout form. MoneyCollect inserts an iframe into this div that securely collects payment information.
<!DOCTYPEhtml><htmllang="en"><head> <metacharset="utf-8" /> <title>Accept a payment</title> <metaname="description"content="A demo of a payment on MoneyCollect" /> <metaname="viewport"content="width=device-width, initial-scale=1" /> <linkrel="stylesheet"href="checkout.css" /></head><body><divclass="sr-root"style="margin: auto;"> <divclass="payment-view" ><!-- Display a payment form --> <formid="payment-form"> <divid="card-element"class="ab-element"><!--MoneyCollect.js injects the Payment Element--> </div> <divclass="sr-field-error"id="card-errors"role="alert"></div> <buttonid="submit"> <divclass="spinner hidden"id="spinner"></div> <spanid="button-text">Pay now</span> </button> <divid="payment-message"class="hidden"style="color:#ff0000"></div> </form> </div> </div><scriptsrc="https://static.moneycollect.com/jssdk/js/MoneyCollect.js"></script><scriptsrc="checkout.js"defer></script></body></html>
Initialize MoneyCollect.js
Initialize MoneyCollect.js with your publishable API keys. You will use MoneyCollect.js to create the Payment Element and complete the payment on the client.
Fetch a Payment
Immediately make a request to the endpoint on your server to create a new Payment as soon as your checkout page loads. The clientSecret,id returned by your endpoint is used to complete the payment.
Initialize MoneyCollect Elements
Initialize the MoneyCollect Elements UI library with the client secret. Elements manages the UI components you need to collect payment details.
// A reference to MoneyCollect.js initialized with a fake API key.var apikey ="API Public key";var moneyCollect;// The items the customer wants to buyvar items = [{ id:"xl-tshirt" }];initialize();// Fetches a payment intent and captures the client secretasyncfunctioninitialize() {constresponse=awaitfetch("/create-payment", { method:"POST", headers: { "Content-Type":"application/json" }, body:JSON.stringify({ items }), });var paymentResponse =awaitresponse.json();setupElements();document.querySelector("#payment-form").addEventListener("submit",function(evt) {evt.preventDefault();// Initiate paymenthandleSubmit(paymentResponse); });}asyncfunctionsetupElements() { moneyCollect =MoneycollectPay(apikey);let params = { formId:'payment-form',// form id frameId:'PrivateFrame',// generated IframeId mode:"test", customerId:"", needCardList:true, autoValidate:true, modelType:"normal", lang:'ko',// Form display and verification information language layout: { pageMode:"inner",// Style mode of the page inner | block style: { frameMaxHeight:"50",// The max height of iframe input: { FontSize:"",// Collect the size of the font FontFamily:"",// Specify a prioritized list of one or more font family names FontWeight:"",// Collect the weight (or boldness) of the font Color:"",// Collect the foreground color value of an element's text ContainerBorder:"",//Collect the name of the font ContainerBg:"",// Collect the weight (or boldness) of the font ContainerSh:""//Collect the color of the font } } } }moneyCollect.elementInit("payment_steps", params);}// Billing Addresslet paymentMethodsData = { billingDetails: { address: { city:"Hong Kong", country:"CN", line1:"193 Prince Edward Road", line2:"", postalCode:"421455", state:"Hong Kong" }, email:"customer@gmail.com", firstName:"su", lastName:"diana", phone:"19112454541" }}asyncfunctionhandleSubmit(paymentResponse) {setLoading(true);moneyCollect.confirmPayment({ paymentMethod: paymentMethodsData, autoJump:false, payment_id:paymentResponse.id, clientSecret:paymentResponse.clientSecret, confirmDetail: {} //Confirm parameters }).then((result) => { if(result.data.code ==="success"){orderComplete(result.data.data); } else { showMessage(result.data.msg); } });setLoading(false);}// Fetches the payment intent status after payment submissionasyncfunctionorderComplete(paymentIntent) {document.querySelectorAll(".payment-view").forEach(function(view) {view.classList.add("hidden"); });document.querySelectorAll(".completed-view").forEach(function(view) {view.classList.remove("hidden"); });document.querySelector(".status").textContent =paymentIntent.status ;var paymentIntentJson =JSON.stringify(paymentIntent,null,2);document.querySelector("pre").textContent = paymentIntentJson;}// ------- UI helpers -------functionshowMessage(messageText) {constmessageContainer=document.querySelector("#payment-message");messageContainer.classList.remove("hidden");messageContainer.textContent = messageText;}// Show a spinner on payment submissionfunctionsetLoading(isLoading) {if (isLoading) {// Disable the button and show a spinnerdocument.querySelector("#submit").disabled =true;document.querySelector("#spinner").classList.remove("hidden");document.querySelector("#button-text").classList.add("hidden"); } else {document.querySelector("#submit").disabled =false;document.querySelector("#spinner").classList.add("hidden");document.querySelector("#button-text").classList.remove("hidden"); }}
Customlize your payment page language
You can customize the page language through setting the parameterlang .
Listen to the form’s submit event to know when to confirm the payment through the MoneyCollect API.
Complete the payment
Call confirmPayment(), passing along the PaymentElement and a return_url to indicate where MoneyCollect should redirect the user after they complete the payment. For payments that require authentication, MoneyCollect displays a modal for 3D Secure authentication or redirects the customer to an authentication page depending on the payment method. After the customer completes the authentication process, they’re redirected to the return_url.
5. Handle post-payment events
Use a webhook
When the notifyUrl parameter is passed, MoneyCollect will use the URL to asynchronously notify the transaction result.
And for detailed guidance on managing webhooks, processing refunds, and handling responses after the payment, please refer to the following documentation.
6. Additional testing resources
There are several test cards you can use to make sure your integration is ready for production. Use them with any CVC, postal code, and future expiration date.