{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"3452932b-10ca-4524-9da6-db7212e9bff7","name":"MVP Integration","description":"Version: 1.0.4\n\nLast updated: 9th December 2024\n\nThis documentation describes how client applications can integrate with Marine Vessel Pass Open Authorization (MVP OAuth) to authorize client applications to access services offered by MVP.\n\n- Prerequisites\n    \n- Open Authorisation Flow\n    \n- Sequence Diagram: Client application integrating MVP\n    \n- Integration Guide: Login via QR Code\n    \n- Change logs\n    \n- Password Login\n    \n    - **POST** Password Grant Type\n        \n    - **GET** Password Authenticator Status\n        \n- QR Code Login\n    \n    - **GET** Display QR Code\n        \n    - **GET** Verify QR Code\n        \n    - **POST** Decrypt Signature (No need for integration)\n        \n    - **GET** Confirm Login (No need for integration)\n        \n    - **POST** Mobile Grant Type\n        \n- Refresh Grant Type\n    \n    - **POST** Refresh Token Grant Type\n        \n- Resources\n    \n    - **GET** Get Account\n        \n    - **POST** Get Ship\n        \n    - **GET** Get Ship Types\n        \n    - **POST** Get Ship History\n        \n    - **POST** Get Company\n        \n    - **POST** Get Company Ships\n        \n- Digital Signing\n    \n    - **POST** Upload PDF Document (Require For **Initialize PDF Document**)\n        \n    - **GET** Get Stamp (Require For **Initialize PDF Document**)\n        \n    - **GET** Get Companies (Require For **Initialize PDF Document**)\n        \n    - **POST** Initialize PDF Document\n        \n    - **POST** Initialize Verifiable QRcode Location, Stamp Locations, Signature Locations\n        \n    - **POST** User Signs PDF Document Digitally\n        \n    - **POST** List of PDF Documents\n        \n\n# Change logs\n\n<u><b>1.0.4 (9 December 2024)</b></u>\n\n- Added password authenticator status: Ship users will need to download the mobile application (iOS/Android) to approve password logins if this feature is enabled\n    \n\n<u><b>1.0.3 (14 October 2024)</b></u>\n\n- Added integration guide for MVP's QR code login\n    \n- Added design guideline for MVP login\n    \n\n<u><b>1.0.2 (17 September 2024)</b></u>\n\n- Migrated documentation from PDF to Postman\n    \n- Added new resources reflecting data from S&P Global's IMO database\n    \n- Added level 2 and level 5 ship type\n    \n\n<u><b>1.0.1 (9 Sept 2024)</b></u>\n\n- Missing username and password for password grant type\n    \n\n<u><b>1.0.0 (24 July 2024)</b></u>\n\n- Initial version\n    \n\n# Prerequisites\n\n## i. Testing Phase\n\n| UAT | **Value** |\n| --- | --- |\n| Web Application URL | [https://uat.marinevesselpass.com](https://uat.marinevesselpass.com) |\n| oauthBaseUrl | [https://uat-auth.marinevesselpass.com](https://uat-auth.marinevesselpass.com) |\n| mvpBaseUrl | [https://uat-api.marinevesselpass.com](https://uat-api.marinevesselpass.com) |\n| gatewayBaseUrl | [https://uat-gateway.marinevesselpass.com](https://uat-gateway.marinevesselpass.com) |\n\ni) Basic Authentication to call the authorisation server  \nClient Id: `Request from Bunkerchain`  \nClient Secret: `Request from Bunkerchain`\n\nii) Ship Account to login to MVP mobile app  \nUsername: `Request from Bunkerchain`  \nPassword: `Request from Bunkerchain`\n\niii) App download link: [https://mvp.bunkerchain.io](https://mvp.bunkerchain.io)\n\niv) In addition, a new client application is required to provide redirect web URLs to receive the new code to exchange for an access token when MVP users scan a QR code to log in to your application. By default, the redirect web URL is [http://localhost:8080/login](http://localhost:8080/login). Please complete the [Google form](https://forms.gle/NixBp9FNov4PxgfPA) to provide your redirect web URLs.\n\n## ii. Going Live\n\nWe take testing and production deployment very seriously. Please contact our tech support when you are ready. Make sure you have completed the [Google form](https://forms.gle/NixBp9FNov4PxgfPA) to provide your redirect web URLs for the different environments.\n\n# Open Authorisation Flow\n\nMVP digital identity makes web authentication easy for any client application in the maritime industry, ensuring that existing or new systems can rest assured that the ship data is validated and accurate. There are two ways to authenticate MVP users on client application: i) `Password login` ii) `QRcode login`\n\n# Sequence Diagram: Client application integrating MVP\n\n<img src=\"https://lh7-rt.googleusercontent.com/docsz/AD_4nXe_wA_5S-krjEaG94YfdL-Hf9mIuZ6NfGchR_kZa4IzZ0_xnKgJhrWpiEAO5zhP1IzB2Shmddpgo0P-20oHG4V4UN6wx6NH3gnaeHS35EwCn03RLEYWisDjDBW8q5mQOQdIHJEMa2-ONIldxGJelA6AWlA?key=Q4r4kGz7iIXyNGfzUsmIjg\">\n\n# Integration Guide: Login via QR Code\n\nAt the end of this tutorial, the client application should be able to allow MVP users to log in using a QR Code. MVP OAuth is following a similar implementation like Singpass from Singapore called OpenID, with slight differences in implementation. This tutorial assumes that any developers reading this documentation has experience with integrating OAuth, so it will be concise while covering the essential steps.\n\n### Step 1: Integrate and scanning the QR Code\n\n1. Integrate **GET QR Code Login** into the login page\n    \n\n``` html\n...\n<iframe src=\"https://uat-auth.marinevesselpass.com/token/qrConnect?client_id=qrcode&amp;redirect_uri=http://localhost:8080/login&state=STATE\">\n</iframe>\n...\n\n ```\n\n1. The authentication process begins when the QR Code is scanned using the MVP mobile app. Download iOS/Android to login as MVP user: [https://mvp.bunkerchain.io](https://mvp.bunkerchain.io)\n    \n2. The client application (e.g., a browser) should automatically start polling the \"GET verify QR Code\" endpoint at regular intervals to check for approval status.\n    \n\n### Step 2: Poll the \"GET verify QR Code\" Endpoint\n\n1. Continue polling the endpoint until the user approves the QR Code login on the MVP app.\n    \n2. Once approved, the endpoint will redirect to a redirect URL. The default redirect URL is `http://localhost:8080/login`, but a custom redirect URL can be provided.\n    \n3. A new code (different code from the QR Code) will be appended to the redirect URL as a query parameter. Eg. `http://localhost:8080/login?code=h1tpRc&state=STATE`\n    \n\n### Step 3: Handling the Redirect and New Code\n\n1. Capture the new code from the redirect URL on the client side. Please complete the [Google form](https://forms.gle/NixBp9FNov4PxgfPA) if you want to redirect to your custom redirect URL.\n    \n2. Then, pass the new code to the client application's backend server.\n    \n\n### Step 4: Exchange the New Code for an Access Token\n\n1. At the backend server, make a `POST` request to **POST** **Mobile Grant Type** to exchange the new code for an access token.\n    \n\n```\ncurl --location --request POST '/oauth/token?grant_type=mobile&mobile=qrcode@{NEW_CODE}&code={NEW_CODE}' \\\n--header 'Accept: application/json' \\\n--header 'Content-Type: application/x-www-form-urlencoded'\n\n ```\n\n1. The access token can then be used to interact with MVP API resources on behalf of the authenticated user.\n    \n\n``` json\n{\n  \"access_token\": \"7f265293-faab-49e4-827c-131aec21a73d\",\n  \"token_type\": \"bearer\",\n  \"refresh_token\": \"c750fb47-8aa1-4eea-a982-25dedcbb657c\",\n  \"expires_in\": 15551999,\n  \"scope\": \"Auth Sign\",\n  \"license\": \"made by mvps\",\n  \"active\": true,\n  \"twoFactorEnabled\": false,\n  \"user_id\": 1744280419377000400,\n  \"client_id\": \"891f855953c74179932cc5a8f9df4a22\",\n  \"username\": \"vesselmaster@bunkerchain.io\"\n}\n\n ```\n\n### Step 5: Use the Access Token to Access MVP API Resources\n\n1. Include the access token in API requests to access various MVP API resources.\n    \n2. Ensure the token is securely handled, as it represents the authenticated user's session.\n    \n\n# Design Guideline For Login Page\n\nHere are some design guidelines for the client application\n\n1. **Consistency in UI Elements**\n    \n    1. **Font and Color Scheme**: Use a consistent font family and size across all screens. The color scheme should also be unified\n        \n        1. Font size: 16px\n            \n        2. Font family: Roboto\n            \n        3. Button Primary Color: #2961FC\n            \n    2. **MVP Logo** should be positioned above the password/QR Code login\n        \n2. **Security Features**\n    \n    1. **Password Visibility Toggle**: Add a toggle button to show or hide the password field, allowing users to double-check their input.\n        \n3. **Mobile Responsiveness**\n    \n    1. **Responsive Layout**: Ensure the form adapts well to smaller screen sizes, with form elements stacking vertically and touch-friendly sizing for buttons and links.\n        \n\n<img src=\"https://content.pstmn.io/edd608dd-9c66-4acb-9a2e-80cd73d938db/MjcwNzE3Mjg5ODAxNjRfLnBpY19oZC5qcGc=\" alt=\"QR%20Code%20login\" width=\"301\" height=\"359\">\n\n<img src=\"https://content.pstmn.io/629fb01f-967b-4f61-867e-08865a92f874/MjcwODE3Mjg5ODAxNjRfLnBpY19oZC5qcGc=\" alt=\"Password%20login\" width=\"299\" height=\"370\">\n\nNOTE:\n\nYou can download the MVP logo and the gradient border [here](https://drive.google.com/file/d/1DjnMslbPGzI0ECAq22sbjeaoBzmUqoSX/view?usp=sharing).\n\nFor the \"Register for Marine Vessel Pass\", insert [https://marinevesselpass.com/onboarding-mvp](https://marinevesselpass.com/onboarding-mvp)\n\nFor the \"Download Marine Vessel Pass\", insert [https://marinevesselpass.com/app](https://marinevesselpass.com/onboarding-mvp)","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"22440738","team":3899121,"collectionId":"3452932b-10ca-4524-9da6-db7212e9bff7","publishedId":"2sAXqng5D2","public":true,"publicUrl":"https://documentation.marinevesselpass.com","privateUrl":"https://go.postman.co/documentation/22440738-3452932b-10ca-4524-9da6-db7212e9bff7","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"documentationLayout":"classic-double-column","customisation":{"metaTags":[{"name":"description","value":""},{"name":"title","value":"MVP OAuth API Integration"}],"appearance":{"default":"system_default","themes":[{"name":"dark","logo":"https://content.pstmn.io/11916b6e-94af-471c-b8e4-1495429981bb/bXZwLnBuZw==","colors":{"top-bar":"212121","right-sidebar":"303030","highlight":"FF6C37"}},{"name":"light","logo":"https://content.pstmn.io/11916b6e-94af-471c-b8e4-1495429981bb/bXZwLnBuZw==","colors":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"}}]}},"version":"8.10.1","publishDate":"2024-09-17T07:50:30.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{"title":"MVP OAuth API Integration","description":""},"logos":{"logoLight":"https://content.pstmn.io/11916b6e-94af-471c-b8e4-1495429981bb/bXZwLnBuZw==","logoDark":"https://content.pstmn.io/11916b6e-94af-471c-b8e4-1495429981bb/bXZwLnBuZw=="}},"statusCode":200},"environments":[{"name":"MVP UAT","id":"ab442b5d-e1b3-47f8-86d1-77e0951d3760","owner":"22440738","values":[{"key":"oauthBaseUrl","value":"","enabled":true,"type":"default"},{"key":"mvpBaseUrl","value":"","enabled":true,"type":"default"},{"key":"clientId","value":"","enabled":true,"type":"default"},{"key":"clientSecret","value":"","enabled":true,"type":"default"},{"key":"username","value":"","enabled":true,"type":"default"},{"key":"password","value":"","enabled":true,"type":"default"},{"key":"accessToken","value":"","enabled":true,"type":"default"},{"key":"refreshToken","value":"","enabled":true,"type":"default"},{"key":"shipImoNumber","value":"","enabled":true,"type":"default"},{"key":"companyImoNumber","value":"","enabled":true,"type":"default"},{"key":"encoded_username","value":"","enabled":true,"type":"any"},{"key":"gatewayBaseUrl","value":"","enabled":true,"type":"default"}],"published":true}],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/f59a868e9b99649badaf5c7a884e9458c30ecdbf01f048b2a70a8cf1172fda91","favicon":"https://marinevesselpass.com/favicon.ico"},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"},{"label":"MVP UAT","value":"22440738-ab442b5d-e1b3-47f8-86d1-77e0951d3760"}],"canonicalUrl":"https://documentation.marinevesselpass.com/view/metadata/2sAXqng5D2"}