Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bd7a72f3c0 | |||
| d1242e5cd2 |
7 changed files with 64 additions and 3036 deletions
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -92,15 +92,8 @@ window.app = Vue.createApp({
|
||||||
testingConnection: false,
|
testingConnection: false,
|
||||||
runningManualPoll: false,
|
runningManualPoll: false,
|
||||||
runningTestTransaction: false,
|
runningTestTransaction: false,
|
||||||
processingSpecificTransaction: false,
|
|
||||||
lamassuConfig: null,
|
lamassuConfig: null,
|
||||||
|
|
||||||
// Manual transaction processing
|
|
||||||
manualTransactionDialog: {
|
|
||||||
show: false,
|
|
||||||
transactionId: ''
|
|
||||||
},
|
|
||||||
|
|
||||||
// Config dialog
|
// Config dialog
|
||||||
configDialog: {
|
configDialog: {
|
||||||
show: false,
|
show: false,
|
||||||
|
|
@ -593,79 +586,6 @@ window.app = Vue.createApp({
|
||||||
await this.getDeposits()
|
await this.getDeposits()
|
||||||
await this.getLamassuTransactions()
|
await this.getLamassuTransactions()
|
||||||
await this.getLamassuConfig()
|
await this.getLamassuConfig()
|
||||||
} catch (error) {
|
|
||||||
LNbits.utils.notifyApiError(error)
|
|
||||||
} finally {
|
|
||||||
this.runningTestTransaction = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
openManualTransactionDialog() {
|
|
||||||
this.manualTransactionDialog.transactionId = ''
|
|
||||||
this.manualTransactionDialog.show = true
|
|
||||||
},
|
|
||||||
|
|
||||||
async processSpecificTransaction() {
|
|
||||||
if (!this.manualTransactionDialog.transactionId) {
|
|
||||||
this.$q.notify({
|
|
||||||
type: 'warning',
|
|
||||||
message: 'Please enter a transaction ID',
|
|
||||||
timeout: 3000
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.processingSpecificTransaction = true
|
|
||||||
try {
|
|
||||||
const { data } = await LNbits.api.request(
|
|
||||||
'POST',
|
|
||||||
`/satmachineadmin/api/v1/dca/process-transaction/${this.manualTransactionDialog.transactionId}`,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
|
|
||||||
if (data.already_processed) {
|
|
||||||
this.$q.notify({
|
|
||||||
type: 'warning',
|
|
||||||
message: `Transaction already processed with ${data.payment_count} distributions`,
|
|
||||||
timeout: 5000
|
|
||||||
})
|
|
||||||
this.manualTransactionDialog.show = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show detailed results
|
|
||||||
const details = data.transaction_details
|
|
||||||
let dialogContent = `<strong>Manual Transaction Processing Results</strong><br/><br/>`
|
|
||||||
dialogContent += `<strong>Transaction ID:</strong> ${details.transaction_id}<br/>`
|
|
||||||
dialogContent += `<strong>Status:</strong> ${details.status}<br/>`
|
|
||||||
dialogContent += `<strong>Dispense:</strong> ${details.dispense ? 'Yes' : 'No'}<br/>`
|
|
||||||
dialogContent += `<strong>Dispense Confirmed:</strong> ${details.dispense_confirmed ? 'Yes' : 'No'}<br/>`
|
|
||||||
dialogContent += `<strong>Crypto Amount:</strong> ${details.crypto_amount} sats<br/>`
|
|
||||||
dialogContent += `<strong>Fiat Amount:</strong> ${details.fiat_amount}<br/>`
|
|
||||||
dialogContent += `<br/><strong>Transaction processed successfully!</strong>`
|
|
||||||
|
|
||||||
this.$q.dialog({
|
|
||||||
title: 'Transaction Processed',
|
|
||||||
message: dialogContent,
|
|
||||||
html: true,
|
|
||||||
ok: {
|
|
||||||
color: 'positive',
|
|
||||||
label: 'Great!'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$q.notify({
|
|
||||||
type: 'positive',
|
|
||||||
message: `Transaction ${details.transaction_id} processed successfully`,
|
|
||||||
timeout: 5000
|
|
||||||
})
|
|
||||||
|
|
||||||
// Close dialog and refresh data
|
|
||||||
this.manualTransactionDialog.show = false
|
|
||||||
await this.getDcaClients()
|
|
||||||
await this.getDeposits()
|
|
||||||
await this.getLamassuTransactions()
|
|
||||||
await this.getLamassuConfig()
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
LNbits.utils.notifyApiError(error)
|
LNbits.utils.notifyApiError(error)
|
||||||
|
|
|
||||||
|
|
@ -335,26 +335,25 @@
|
||||||
>
|
>
|
||||||
Test Connection
|
Test Connection
|
||||||
</q-btn>
|
</q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
v-if="lamassuConfig"
|
v-if="lamassuConfig"
|
||||||
size="sm"
|
size="sm"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
@click="manualPoll"
|
@click="manualPoll"
|
||||||
:loading="runningManualPoll"
|
:loading="runningManualPoll"
|
||||||
class="q-ml-sm"
|
class="q-ml-sm"
|
||||||
>
|
>
|
||||||
Manual Poll
|
Manual Poll
|
||||||
</q-btn>
|
</q-btn>
|
||||||
<q-btn
|
<q-btn
|
||||||
v-if="lamassuConfig"
|
v-if="lamassuConfig && lamassuConfig.source_wallet_id"
|
||||||
size="sm"
|
size="sm"
|
||||||
color="deep-orange"
|
color="warning"
|
||||||
@click="openManualTransactionDialog"
|
@click="testTransaction"
|
||||||
|
:loading="runningTestTransaction"
|
||||||
class="q-ml-sm"
|
class="q-ml-sm"
|
||||||
icon="build"
|
|
||||||
>
|
>
|
||||||
<q-tooltip>Process specific transaction by ID (bypasses dispense checks)</q-tooltip>
|
Test Transaction
|
||||||
Manual TX
|
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
|
|
@ -691,7 +690,7 @@
|
||||||
<q-dialog v-model="distributionDialog.show" position="top" maximized>
|
<q-dialog v-model="distributionDialog.show" position="top" maximized>
|
||||||
<q-card class="q-pa-lg">
|
<q-card class="q-pa-lg">
|
||||||
<div class="text-h6 q-mb-md">Transaction Distribution Details</div>
|
<div class="text-h6 q-mb-md">Transaction Distribution Details</div>
|
||||||
|
|
||||||
<div v-if="distributionDialog.transaction" class="q-mb-lg">
|
<div v-if="distributionDialog.transaction" class="q-mb-lg">
|
||||||
<q-list>
|
<q-list>
|
||||||
<q-item>
|
<q-item>
|
||||||
|
|
@ -710,7 +709,7 @@
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label caption>Total Amount</q-item-label>
|
<q-item-label caption>Total Amount</q-item-label>
|
||||||
<q-item-label>
|
<q-item-label>
|
||||||
${ formatCurrency(distributionDialog.transaction.fiat_amount) }
|
${ formatCurrency(distributionDialog.transaction.fiat_amount) }
|
||||||
(${ formatSats(distributionDialog.transaction.crypto_amount) })
|
(${ formatSats(distributionDialog.transaction.crypto_amount) })
|
||||||
</q-item-label>
|
</q-item-label>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
|
|
@ -719,7 +718,7 @@
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
<q-item-label caption>Commission</q-item-label>
|
<q-item-label caption>Commission</q-item-label>
|
||||||
<q-item-label>
|
<q-item-label>
|
||||||
${ (distributionDialog.transaction.commission_percentage * 100).toFixed(1) }%
|
${ (distributionDialog.transaction.commission_percentage * 100).toFixed(1) }%
|
||||||
<span v-if="distributionDialog.transaction.discount > 0">
|
<span v-if="distributionDialog.transaction.discount > 0">
|
||||||
(with ${ distributionDialog.transaction.discount }% discount = ${ (distributionDialog.transaction.effective_commission * 100).toFixed(1) }% effective)
|
(with ${ distributionDialog.transaction.discount }% discount = ${ (distributionDialog.transaction.effective_commission * 100).toFixed(1) }% effective)
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -741,11 +740,11 @@
|
||||||
</q-item>
|
</q-item>
|
||||||
</q-list>
|
</q-list>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<q-separator class="q-my-md"></q-separator>
|
<q-separator class="q-my-md"></q-separator>
|
||||||
|
|
||||||
<div class="text-h6 q-mb-md">Client Distributions</div>
|
<div class="text-h6 q-mb-md">Client Distributions</div>
|
||||||
|
|
||||||
<q-table
|
<q-table
|
||||||
dense
|
dense
|
||||||
flat
|
flat
|
||||||
|
|
@ -772,71 +771,12 @@
|
||||||
</q-tr>
|
</q-tr>
|
||||||
</template>
|
</template>
|
||||||
</q-table>
|
</q-table>
|
||||||
|
|
||||||
<div class="row q-mt-lg">
|
<div class="row q-mt-lg">
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
<q-btn v-close-popup flat color="grey" class="q-ml-auto">Close</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</q-card>
|
</q-card>
|
||||||
</q-dialog>
|
</q-dialog>
|
||||||
|
|
||||||
<!--/////////////////////////////////////////////////-->
|
|
||||||
<!--//////////////MANUAL TRANSACTION DIALOG///////////-->
|
|
||||||
<!--/////////////////////////////////////////////////-->
|
|
||||||
|
|
||||||
<q-dialog v-model="manualTransactionDialog.show" position="top">
|
|
||||||
<q-card class="q-pa-lg q-pt-xl" style="width: 500px; max-width: 90vw">
|
|
||||||
<div class="text-h6 q-mb-md">Process Specific Transaction</div>
|
|
||||||
|
|
||||||
<q-banner class="bg-orange-1 text-orange-9 q-mb-md">
|
|
||||||
<template v-slot:avatar>
|
|
||||||
<q-icon name="warning" color="orange" />
|
|
||||||
</template>
|
|
||||||
<div class="text-caption">
|
|
||||||
<strong>Use with caution:</strong> This bypasses all dispense status checks and will process the transaction even if dispense_confirmed is false. Only use this for manually settled transactions.
|
|
||||||
</div>
|
|
||||||
</q-banner>
|
|
||||||
|
|
||||||
<q-form @submit="processSpecificTransaction" class="q-gutter-md">
|
|
||||||
<q-input
|
|
||||||
filled
|
|
||||||
dense
|
|
||||||
v-model.trim="manualTransactionDialog.transactionId"
|
|
||||||
label="Lamassu Transaction ID *"
|
|
||||||
placeholder="e.g., 82746dfb-674d-4d7e-b008-7507caa02773"
|
|
||||||
hint="Enter the transaction/session ID from Lamassu database"
|
|
||||||
>
|
|
||||||
<template v-slot:prepend>
|
|
||||||
<q-icon name="receipt" />
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
|
|
||||||
<div class="text-caption text-grey-7">
|
|
||||||
This will:
|
|
||||||
<ul class="q-my-sm">
|
|
||||||
<li>Fetch the transaction from Lamassu regardless of dispense status</li>
|
|
||||||
<li>Process it through the normal DCA distribution flow</li>
|
|
||||||
<li>Credit the source wallet and distribute to clients</li>
|
|
||||||
<li>Send commission to the commission wallet (if configured)</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row q-mt-lg">
|
|
||||||
<q-btn
|
|
||||||
unelevated
|
|
||||||
color="deep-orange"
|
|
||||||
type="submit"
|
|
||||||
:loading="processingSpecificTransaction"
|
|
||||||
:disable="!manualTransactionDialog.transactionId"
|
|
||||||
>
|
|
||||||
Process Transaction
|
|
||||||
</q-btn>
|
|
||||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto">
|
|
||||||
Cancel
|
|
||||||
</q-btn>
|
|
||||||
</div>
|
|
||||||
</q-form>
|
|
||||||
</q-card>
|
|
||||||
</q-dialog>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -560,44 +560,6 @@ class LamassuTransactionProcessor:
|
||||||
logger.error(f"Error executing SSH query: {e}")
|
logger.error(f"Error executing SSH query: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
async def fetch_transaction_by_id(self, db_config: Dict[str, Any], transaction_id: str) -> Optional[Dict[str, Any]]:
|
|
||||||
"""Fetch a specific transaction by ID from Lamassu database, bypassing all status filters"""
|
|
||||||
try:
|
|
||||||
logger.info(f"Fetching transaction {transaction_id} from Lamassu database (bypass all filters)")
|
|
||||||
|
|
||||||
# Query for specific transaction ID without any status/dispense filters
|
|
||||||
lamassu_query = f"""
|
|
||||||
SELECT
|
|
||||||
co.id as transaction_id,
|
|
||||||
co.fiat as fiat_amount,
|
|
||||||
co.crypto_atoms as crypto_amount,
|
|
||||||
co.confirmed_at as transaction_time,
|
|
||||||
co.device_id,
|
|
||||||
co.status,
|
|
||||||
co.commission_percentage,
|
|
||||||
co.discount,
|
|
||||||
co.crypto_code,
|
|
||||||
co.fiat_code,
|
|
||||||
co.dispense,
|
|
||||||
co.dispense_confirmed
|
|
||||||
FROM cash_out_txs co
|
|
||||||
WHERE co.id = '{transaction_id}'
|
|
||||||
"""
|
|
||||||
|
|
||||||
results = await self.execute_ssh_query(db_config, lamassu_query)
|
|
||||||
|
|
||||||
if not results:
|
|
||||||
logger.warning(f"Transaction {transaction_id} not found in Lamassu database")
|
|
||||||
return None
|
|
||||||
|
|
||||||
transaction = results[0]
|
|
||||||
logger.info(f"Found transaction {transaction_id}: status={transaction.get('status')}, dispense={transaction.get('dispense')}, dispense_confirmed={transaction.get('dispense_confirmed')}")
|
|
||||||
return transaction
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Error fetching transaction {transaction_id} from Lamassu database: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def fetch_new_transactions(self, db_config: Dict[str, Any]) -> List[Dict[str, Any]]:
|
async def fetch_new_transactions(self, db_config: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||||
"""Fetch new successful transactions from Lamassu database since last poll"""
|
"""Fetch new successful transactions from Lamassu database since last poll"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -611,13 +573,13 @@ class LamassuTransactionProcessor:
|
||||||
# Fallback to last 24 hours for first run or if no previous poll
|
# Fallback to last 24 hours for first run or if no previous poll
|
||||||
time_threshold = datetime.now(timezone.utc) - timedelta(hours=24)
|
time_threshold = datetime.now(timezone.utc) - timedelta(hours=24)
|
||||||
logger.info(f"No previous poll found, checking last 24 hours since: {time_threshold}")
|
logger.info(f"No previous poll found, checking last 24 hours since: {time_threshold}")
|
||||||
|
|
||||||
# Convert to UTC if not already timezone-aware
|
# Convert to UTC if not already timezone-aware
|
||||||
if time_threshold.tzinfo is None:
|
if time_threshold.tzinfo is None:
|
||||||
time_threshold = time_threshold.replace(tzinfo=timezone.utc)
|
time_threshold = time_threshold.replace(tzinfo=timezone.utc)
|
||||||
elif time_threshold.tzinfo != timezone.utc:
|
elif time_threshold.tzinfo != timezone.utc:
|
||||||
time_threshold = time_threshold.astimezone(timezone.utc)
|
time_threshold = time_threshold.astimezone(timezone.utc)
|
||||||
|
|
||||||
# Format as UTC for database query
|
# Format as UTC for database query
|
||||||
time_threshold_str = time_threshold.strftime('%Y-%m-%d %H:%M:%S UTC')
|
time_threshold_str = time_threshold.strftime('%Y-%m-%d %H:%M:%S UTC')
|
||||||
|
|
||||||
|
|
|
||||||
158
views_api.py
158
views_api.py
|
|
@ -233,139 +233,69 @@ async def api_manual_poll(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@satmachineadmin_api_router.post("/api/v1/dca/process-transaction/{transaction_id}")
|
@satmachineadmin_api_router.post("/api/v1/dca/test-transaction")
|
||||||
async def api_process_specific_transaction(
|
async def api_test_transaction(
|
||||||
transaction_id: str,
|
|
||||||
user: User = Depends(check_super_user),
|
user: User = Depends(check_super_user),
|
||||||
):
|
crypto_atoms: int = 103,
|
||||||
"""
|
commission_percentage: float = 0.03,
|
||||||
Manually process a specific Lamassu transaction by ID, bypassing all status filters.
|
discount: float = 0.0,
|
||||||
|
) -> dict:
|
||||||
This endpoint is useful for processing transactions that were manually settled
|
"""Test transaction processing with simulated Lamassu transaction data"""
|
||||||
or had dispense issues but need to be included in DCA distribution.
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
from .transaction_processor import transaction_processor
|
from .transaction_processor import transaction_processor
|
||||||
from .crud import get_payments_by_lamassu_transaction
|
import uuid
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
# Get database configuration
|
# Create a mock transaction that mimics Lamassu database structure
|
||||||
db_config = await transaction_processor.connect_to_lamassu_db()
|
mock_transaction = {
|
||||||
if not db_config:
|
"transaction_id": str(uuid.uuid4())[:8], # Short ID for testing
|
||||||
raise HTTPException(
|
"crypto_amount": crypto_atoms, # Total sats including commission
|
||||||
status_code=HTTPStatus.SERVICE_UNAVAILABLE,
|
"fiat_amount": 100, # Mock fiat amount (100 centavos = 1 GTQ)
|
||||||
detail="Could not get Lamassu database configuration",
|
"commission_percentage": commission_percentage, # Already as decimal
|
||||||
)
|
"discount": discount,
|
||||||
|
"transaction_time": datetime.now(timezone.utc),
|
||||||
|
"crypto_code": "BTC",
|
||||||
|
"fiat_code": "GTQ",
|
||||||
|
"device_id": "test_device",
|
||||||
|
"status": "confirmed",
|
||||||
|
}
|
||||||
|
|
||||||
# Check if transaction was already processed
|
# Process the mock transaction through the complete DCA flow
|
||||||
existing_payments = await get_payments_by_lamassu_transaction(transaction_id)
|
await transaction_processor.process_transaction(mock_transaction)
|
||||||
if existing_payments:
|
|
||||||
return {
|
|
||||||
"success": False,
|
|
||||||
"already_processed": True,
|
|
||||||
"message": f"Transaction {transaction_id} was already processed with {len(existing_payments)} distributions",
|
|
||||||
"payment_count": len(existing_payments),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fetch the specific transaction from Lamassu (bypassing all filters)
|
# Calculate commission for response
|
||||||
transaction = await transaction_processor.fetch_transaction_by_id(db_config, transaction_id)
|
if commission_percentage > 0:
|
||||||
|
effective_commission = commission_percentage * (100 - discount) / 100
|
||||||
if not transaction:
|
base_crypto_atoms = int(crypto_atoms / (1 + effective_commission))
|
||||||
raise HTTPException(
|
commission_amount_sats = crypto_atoms - base_crypto_atoms
|
||||||
status_code=HTTPStatus.NOT_FOUND,
|
else:
|
||||||
detail=f"Transaction {transaction_id} not found in Lamassu database",
|
base_crypto_atoms = crypto_atoms
|
||||||
)
|
commission_amount_sats = 0
|
||||||
|
|
||||||
# Process the transaction through normal DCA flow
|
|
||||||
await transaction_processor.process_transaction(transaction)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"message": f"Transaction {transaction_id} processed successfully",
|
"message": "Test transaction processed successfully",
|
||||||
"transaction_details": {
|
"transaction_details": {
|
||||||
"transaction_id": transaction_id,
|
"transaction_id": mock_transaction["transaction_id"],
|
||||||
"status": transaction.get("status"),
|
"total_amount_sats": crypto_atoms,
|
||||||
"dispense": transaction.get("dispense"),
|
"base_amount_sats": base_crypto_atoms,
|
||||||
"dispense_confirmed": transaction.get("dispense_confirmed"),
|
"commission_amount_sats": commission_amount_sats,
|
||||||
"crypto_amount": transaction.get("crypto_amount"),
|
"commission_percentage": commission_percentage
|
||||||
"fiat_amount": transaction.get("fiat_amount"),
|
* 100, # Show as percentage
|
||||||
|
"effective_commission": effective_commission * 100
|
||||||
|
if commission_percentage > 0
|
||||||
|
else 0,
|
||||||
|
"discount": discount,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
except HTTPException:
|
|
||||||
raise
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||||
detail=f"Error processing transaction {transaction_id}: {str(e)}",
|
detail=f"Error processing test transaction: {str(e)}",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# COMMENTED OUT FOR PRODUCTION - Test transaction endpoint disabled
|
|
||||||
# Uncomment only for development/debugging purposes
|
|
||||||
#
|
|
||||||
# @satmachineadmin_api_router.post("/api/v1/dca/test-transaction")
|
|
||||||
# async def api_test_transaction(
|
|
||||||
# user: User = Depends(check_super_user),
|
|
||||||
# crypto_atoms: int = 103,
|
|
||||||
# commission_percentage: float = 0.03,
|
|
||||||
# discount: float = 0.0,
|
|
||||||
# ) -> dict:
|
|
||||||
# """Test transaction processing with simulated Lamassu transaction data"""
|
|
||||||
# try:
|
|
||||||
# from .transaction_processor import transaction_processor
|
|
||||||
# import uuid
|
|
||||||
# from datetime import datetime, timezone
|
|
||||||
#
|
|
||||||
# # Create a mock transaction that mimics Lamassu database structure
|
|
||||||
# mock_transaction = {
|
|
||||||
# "transaction_id": str(uuid.uuid4())[:8], # Short ID for testing
|
|
||||||
# "crypto_amount": crypto_atoms, # Total sats including commission
|
|
||||||
# "fiat_amount": 100, # Mock fiat amount (100 centavos = 1 GTQ)
|
|
||||||
# "commission_percentage": commission_percentage, # Already as decimal
|
|
||||||
# "discount": discount,
|
|
||||||
# "transaction_time": datetime.now(timezone.utc),
|
|
||||||
# "crypto_code": "BTC",
|
|
||||||
# "fiat_code": "GTQ",
|
|
||||||
# "device_id": "test_device",
|
|
||||||
# "status": "confirmed",
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# # Process the mock transaction through the complete DCA flow
|
|
||||||
# await transaction_processor.process_transaction(mock_transaction)
|
|
||||||
#
|
|
||||||
# # Calculate commission for response
|
|
||||||
# if commission_percentage > 0:
|
|
||||||
# effective_commission = commission_percentage * (100 - discount) / 100
|
|
||||||
# base_crypto_atoms = int(crypto_atoms / (1 + effective_commission))
|
|
||||||
# commission_amount_sats = crypto_atoms - base_crypto_atoms
|
|
||||||
# else:
|
|
||||||
# base_crypto_atoms = crypto_atoms
|
|
||||||
# commission_amount_sats = 0
|
|
||||||
#
|
|
||||||
# return {
|
|
||||||
# "success": True,
|
|
||||||
# "message": "Test transaction processed successfully",
|
|
||||||
# "transaction_details": {
|
|
||||||
# "transaction_id": mock_transaction["transaction_id"],
|
|
||||||
# "total_amount_sats": crypto_atoms,
|
|
||||||
# "base_amount_sats": base_crypto_atoms,
|
|
||||||
# "commission_amount_sats": commission_amount_sats,
|
|
||||||
# "commission_percentage": commission_percentage
|
|
||||||
# * 100, # Show as percentage
|
|
||||||
# "effective_commission": effective_commission * 100
|
|
||||||
# if commission_percentage > 0
|
|
||||||
# else 0,
|
|
||||||
# "discount": discount,
|
|
||||||
# },
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# except Exception as e:
|
|
||||||
# raise HTTPException(
|
|
||||||
# status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
||||||
# detail=f"Error processing test transaction: {str(e)}",
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
# Lamassu Transaction Endpoints
|
# Lamassu Transaction Endpoints
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue