Adjust PayU QR request defaults
All checks were successful
build-and-deploy / build-deploy (push) Successful in 36s

This commit is contained in:
androidlover5842
2026-01-30 06:59:41 +05:30
parent 10c24f265f
commit d278eca1e1
2 changed files with 31 additions and 8 deletions

View File

@@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.client.RestTemplate
import org.springframework.web.server.ResponseStatusException
import jakarta.servlet.http.HttpServletRequest
import java.security.MessageDigest
import java.time.OffsetDateTime
import java.util.UUID
@@ -47,7 +48,8 @@ class PayuQrPayments(
@PathVariable propertyId: UUID,
@PathVariable bookingId: UUID,
@AuthenticationPrincipal principal: MyPrincipal?,
@RequestBody request: PayuQrGenerateRequest
@RequestBody request: PayuQrGenerateRequest,
httpRequest: HttpServletRequest
): PayuQrGenerateResponse {
requireRole(propertyAccess, propertyId, principal, Role.ADMIN, Role.MANAGER, Role.FINANCE)
@@ -72,14 +74,21 @@ class PayuQrPayments(
if (pending <= 0) {
throw ResponseStatusException(HttpStatus.CONFLICT, "No pending amount")
}
val requestedAmount = request.amount?.takeIf { it > 0 }
if (requestedAmount != null && requestedAmount > pending) {
throw ResponseStatusException(HttpStatus.CONFLICT, "Amount exceeds pending")
}
val amountLong = requestedAmount ?: pending
val txnid = "QR${bookingId.toString().substring(0, 8)}${System.currentTimeMillis()}"
val productInfo = "Booking $bookingId"
val firstname = request.customerName?.trim()?.ifBlank { null } ?: "Guest"
val email = request.customerEmail?.trim()?.ifBlank { null } ?: "guest@example.com"
val phone = request.customerPhone?.trim()?.ifBlank { null }
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "customerPhone required")
val amount = String.format("%.2f", pending.toDouble())
val guest = booking.primaryGuest
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Booking missing guest")
val firstname = guest.name?.trim()?.ifBlank { null } ?: "Guest"
val phone = guest.phoneE164?.trim()?.ifBlank { null }
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Guest phone missing")
val email = "guest-${bookingId.toString().substring(0, 8)}@hoteltrisolaris.in"
val amount = String.format("%.2f", amountLong.toDouble())
val udf1 = bookingId.toString()
val udf2 = propertyId.toString()
@@ -129,6 +138,7 @@ class PayuQrPayments(
if (udf5.isNotBlank()) add("udf5", udf5)
add("txn_s2s_flow", "4")
val clientIp = request.clientIp?.trim()?.ifBlank { null }
?: extractClientIp(httpRequest)
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "clientIp required")
val deviceInfo = request.deviceInfo?.trim()?.ifBlank { null }
?: throw ResponseStatusException(HttpStatus.BAD_REQUEST, "deviceInfo required")
@@ -154,7 +164,7 @@ class PayuQrPayments(
property = booking.property,
booking = booking,
txnid = txnid,
amount = pending,
amount = amountLong,
currency = booking.property.currency,
status = PayuQrStatus.CREATED,
requestPayload = requestPayload,
@@ -179,7 +189,7 @@ class PayuQrPayments(
return PayuQrGenerateResponse(
txnid = txnid,
amount = pending,
amount = amountLong,
currency = booking.property.currency,
payuResponse = responseBody
)
@@ -209,6 +219,18 @@ class PayuQrPayments(
return bytes.joinToString("") { "%02x".format(it) }
}
private fun extractClientIp(request: HttpServletRequest): String? {
val forwarded = request.getHeader("X-Forwarded-For")
?.split(",")
?.firstOrNull()
?.trim()
?.ifBlank { null }
if (forwarded != null) return forwarded
val realIp = request.getHeader("X-Real-IP")?.trim()?.ifBlank { null }
if (realIp != null) return realIp
return request.remoteAddr?.trim()?.ifBlank { null }
}
private fun computeExpectedPay(stays: List<com.android.trisolarisserver.models.room.RoomStay>, timezone: String?): Long {
if (stays.isEmpty()) return 0
val now = nowForProperty(timezone)

View File

@@ -21,6 +21,7 @@ data class PayuSettingsResponse(
)
data class PayuQrGenerateRequest(
val amount: Long? = null,
val customerName: String? = null,
val customerEmail: String? = null,
val customerPhone: String? = null,