Skip to content

Commit

Permalink
Merge pull request #197 from ScaleMote/feature/make-payment
Browse files Browse the repository at this point in the history
Feature/make payment
  • Loading branch information
ivanbelasich authored Feb 15, 2024
2 parents 3ab98ab + 7544410 commit 6fb9ee9
Show file tree
Hide file tree
Showing 24 changed files with 799 additions and 140 deletions.
27 changes: 13 additions & 14 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@ name: Build

on:
push:
branches: ['main']
branches: ['main']
pull_request:
branches: ['*']

branches: ['*']

jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ jobs:
VITE_HORIZON_NETWORK_PASSPHRASE: Test SDF Network ; September 2015
VITE_STELLAR_NETWORK: ${{ secrets.VITE_STELLAR_NETWORK }}
CYPRESS_SIMPLE_SIGNER_PRIVATE_KEY: ${{ secrets.SIMPLE_SIGNER_PRIVATE_KEY }}
VITE_HORIZON_URL: ${{ secrets.VITE_HORIZON_URL }}
test:
runs-on: ubuntu-latest
needs: install-cache
Expand Down
114 changes: 113 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ you want to contribute.

# How to implement Simple Signer on your website

Simple Signer provides two endpoints, `/connect` and `/sign` which allow some customisations to be made.
Simple Signer provides three endpoints, `/connect`, `/sign` and `/payment` which allow some customisations to be made.

To see an example of all the implementation properties please take a look at the [test.html](./test.html) file provided
in this repo.
Expand Down Expand Up @@ -329,6 +329,118 @@ Sometimes it's useful to group operations together to explain what they are doin

---

## Making a payment

To make a payment using Simple Signer, you need to provide the necessary parameters either through the URL or using the `postMessage` method. Follow the steps below to integrate the payment functionality into your web application:

### Step 1: Specify Payment Parameters

You can pass the payment parameters such as the receiver's account, amount, asset type, and issuer through the URL or `postMessage` method. Here's an example of how you can do it:

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Simple Signer - Make Payment Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script
src="https://cdnjs.cloudflare.com/ajax/libs/stellar-sdk/10.1.0/stellar-sdk.min.js"
integrity="sha512-EqNQsxKR6rZ5xKl29xXa+ez7xgtVSUpj9UDzZmTqoyF0wHbusLkrP8S7dOsKa9DmkoHbssoWUA4+n/0KYY1EAQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
</head>
<body>
<h1>Make Payment</h1>
<p>
This page demonstrates the process of making a payment using the
Simple Signer.
</p>
<h2>Usage</h2>
<p>Click the "Make Payment" button to initiate the payment process.</p>
<button onclick="makePayment()">Make Payment</button>

<script>
async function makePayment() {
// Define payment parameters
const receiver = 'Receiver public key';
const amount = '10';
const assetCode = 'native'; // 'native' for XLM, or asset code for other assets
const issuer = ''; // If assetCode is not 'native', provide issuer's public key
// Open payment window with payment parameters
const paymentWindow = window.open(
`${simpleSignerUrl}/payment/?receiver=${receiver}&amount=${amount}&assetCode=${assetCode}&issuer=${issuer}`,
'Payment_Window',
'width=360, height=700',
);
// Listen for payment completion message
window.addEventListener('message', async (event) => {
if (event.origin !== simpleSignerUrl) return;
const { type, message } = event.data;
if (type === 'onPayment') {
// Handle payment completion
console.log('Payment completed successfully:', message);
}
});
}
</script>
</body>
</html>
```

You may choose to pass the payment parameters to Simple Signer either via URL or via postMessage.

Via URL:

```javascript
const receiver = 'Receiver public key';
const amount = '10';
const assetCode = 'native'; // 'native' for XLM, or asset code for other assets
const issuer = ''; // If assetCode is not 'native', provide issuer's public key

const paymentWindow = window.open(
`https://sign.scalemote.io/payment/?receiver=${receiver}&amount=${amount}&assetCode=${assetCode}&issuer=${issuer}`,
'Payment_Window',
'width=360, height=700',
);
```

Via PostMessage:

Post Message has some advantages over the URL method which are covered in the Payment API section.

```javascript
const receiver = 'Receiver public key';
const amount = '10';
const assetCode = 'native'; // 'native' for XLM, or asset code for other assets
const issuer = ''; // If assetCode is not 'native', provide issuer's public key

const simpleSignerUrl = 'https://sign.scalemote.io';
const paymentWindow = window.open(
`${simpleSignerUrl}/payment`,
'Payment_Window',
'width=360, height=700',
);

window.addEventListener('message', (e) => {
if (
e.origin !== simpleSignerUrl &&
e.data.type === 'onReady' &&
e.data.page === 'payment'
) {
paymentWindow.postMessage(
{ receiver, amount, assetCode, issuer },
simpleSignerUrl,
);
}
});
```

## Language selection

By default, Simple Signer will detect the browser's language and serve Simple Signer using this configuration. If the
Expand Down
6 changes: 6 additions & 0 deletions cypress/fixtures/payment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"destinationAccount": "GCECUYXE32PPYKPVYOSILACOCUGMEZSDO7GYERC2GKAG2HM34BLMMOMB",
"amountToSend": 100,
"assetCode": "native",
"issuer": "none"
}
14 changes: 14 additions & 0 deletions cypress/integration/ui/events_spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// <reference types="cypress" />
/// <reference types="@testing-library/cypress"/>
import { operationsXdr } from '../../fixtures/operations.json';
import { amountToSend, assetCode, destinationAccount, issuer } from '../../fixtures/payment.json';

const operationGroupTitle = 'Payment';
const operationGroupDescription = 'This is a merge account operation';
Expand Down Expand Up @@ -37,4 +38,17 @@ describe('Events', () => {
cy.get('.tx-operation-container').should('have.length', 2);
cy.get('.tx-description-container').contains(operationDescription);
});

it('should render a payment operation', () => {
cy.visit('/payment');
cy.window().then((win) => {
win.postMessage({
receiver: destinationAccount,
issuer,
amount: amountToSend,
assetCode,
});
});
cy.get('.receiver').should('have.length', 1);
});
});
9 changes: 9 additions & 0 deletions cypress/integration/ui/logout_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,13 @@ describe('logout', () => {
cy.get('.logout-active').contains('Logout').click();
cy.url().should('include', '/connect');
});

it('Should logout on /payment', () => {
cy.visit('/payment');
window.localStorage.setItem('wallet', 'xbull');
cy.wait(5000);
cy.get('.logout-button').click();
cy.get('.logout-active').contains('Logout').click();
cy.url().should('include', '/connect');
});
});
29 changes: 29 additions & 0 deletions cypress/integration/ui/payment_spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/// <reference types="cypress" />
/// <reference types="@testing-library/cypress"/>
import { amountToSend, assetCode, destinationAccount, issuer } from '../../fixtures/payment.json';

describe('checks that the /payment component works', () => {
const BASE_URL = '/payment';

it('should visit /payment with payment information but user is not connected', () => {
cy.visit(
`${BASE_URL}?receiver=${destinationAccount}&amount=${amountToSend}&assetCode=${assetCode}&issuer=${issuer}`,
);
cy.get('.user-not-connected').contains('User is not connected');
cy.get('.payment-btn').click();
cy.url().should('include', '/connect');
});

it('should render payment information if payment parameters are valid', () => {
window.localStorage.setItem('wallet', 'xbull');
cy.visit(
`${BASE_URL}?receiver=${destinationAccount}&amount=${amountToSend}&assetCode=${assetCode}&issuer=${issuer}`,
);
cy.get('.simple-signer').contains(`You are paying ${amountToSend} XLM to the account ${destinationAccount}.`);
});

it('should render an error if payment parameters was not provided', () => {
cy.visit(`${BASE_URL}?receiver=${destinationAccount}`);
cy.get('.simple-signer').contains("Sorry, the recipient's data wasn't provided.");
});
});
Loading

0 comments on commit 6fb9ee9

Please sign in to comment.